我是Ruby的新手,正在使用“Programming Ruby 1.9”(PickAxe)学习它。在书中,我看到了一个我修改过的程序:
1 #!/usr/bin/env ruby -w
2
3 class BookInStock
4 attr_reader :isbn
5 attr_accessor :price
6 def initialize(isbn, price)
7 @isbn = isbn
8 @price = Float(price)
9 end
10 # def price=(price)
11 # @price = Float(price)
12 # end
13 end
14
15 b1 = BookInStock.new("isbn1", 3)
16 p b1
17 b2 = BookInStock.new("isbn2", 3.14)
18 p b2
19 b3 = BookInStock.new("isbn3", "5.67")
20 p b3
21 b3.price = "10.32"
22 p b3
第8行确保将正确的值分配给b3.price
。
但是如何在不使用第10-12行的方法的情况下处理第21行的情况?
我有什么方法可以为此修改attr_accessor
吗?或者我要求太多:D
我在网上找不到任何此类参考资料。
答案 0 :(得分:2)
attr_accessor :sym
是Class的一种方法,它定义了简单的getter和setter方法。
您可以定义自己的casting_attr_accessor
:
class Class
def casting_attr_accessor(accessor, type)
define_method(accessor) do
instance_variable_get("@#{accessor}")
end
define_method("#{accessor}=") do |val|
instance_variable_set("@#{accessor}", Kernel.send(type.to_s, val))
end
end
end
然后在你的班级中使用它
casting_attr_accessor :price, Float
答案 1 :(得分:1)
如果不编写自己的setter方法,就无法做到这一点。内部attr_accessor :method
所做的只是为您生成最简单的setter方法:
def method=(val)
@method = val
end
您需要手动编写更高级的setter方法(在您的情况下setter将包含字符串到浮点转换)。
答案 2 :(得分:1)
是的,你要求的太多了。您必须完全按照注释掉的代码定义price=
。
attr_accessor
只是一种定义
def price=(val)
@price = val
end
(没有类型转换)加上getter方法。
显然,当您定义price=
时,不再需要attr_accessor :price
(仅attr_reader
)。
最后,我宁愿写val.to_f
而不是Float(val)
。