在attr_accessor期间键入强制转换值

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

我在网上找不到任何这样的参考资料。

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 

如果不编写自己的setter方法,就无法做到这一点。 什么attr_accessor :method内部只是生成最简单的setter方法:

 def method=(val) @method = val end 

您需要手动编写更高级的setter方法(在您的情况下setter将包含字符串到浮点转换)。

是的,你要的太多了。 您必须在注释掉的代码中完全定义price=

attr_accessor只是一种简化的定义方式

 def price=(val) @price = val end 

(没有类型转换)加上getter方法。

显然,当你定义price= ,不再需要attr_accessor :price (只有attr_reader )。

最后,我宁愿写val.to_f而不是Float(val)