在attr_accessor期间键入强制转换值

时间:2012-01-20 10:18:10

标签: ruby

我是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

我在网上找不到任何此类参考资料。

3 个答案:

答案 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)