在attr_accessor过程中类型转换值

cbjzeqam  于 2022-09-21  发布在  Ruby
关注(0)|答案(4)|浏览(107)

我是Ruby的新手,正在使用“编程Ruby 1.9”(镐)学习Ruby。在书中,我看到了一个程序,我这样修改了它:

第8行确保将正确的值分配给b3.price

但是,在不使用第10-12行这样的方法的情况下,如何处理第21行这样的情况呢?

有什么方法可以为此修改attr_accessor吗?还是我要求得太多了?

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

s4chpxco

s4chpxco1#

attr_accessor :sym是定义简单的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
1aaf6o9v

1aaf6o9v2#

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

def method=(val)
    @method = val
end

您需要手动编写更高级的setter方法(在本例中,setter将包含字符串到浮点数的转换)。

cu6pst1q

cu6pst1q3#

是的,你的要求太高了。您必须完全按照注解代码中的定义来定义price=

attr_accessor只是定义

def price=(val)
  @price = val
end

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

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

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

5vf7fwbs

5vf7fwbs4#

基于Tomgi Answer,这是一个支持多个属性的版本,因此您可以使用

casting_attr_accessor :price, :amount, Float

放在加载路径中的某个位置,在Rails中我使用初始值设定项


# config/initializers/casting_attr_accessor.rb

# https://stackoverflow.com/a/8940255/287166

class Class
  def casting_attr_accessor(*accessors, type)
    Array(accessors).each do |accessor|
      define_method(accessor) do
        instance_variable_get("@#{accessor}")
      end

      define_method("#{accessor}=") do |val|
        instance_variable_set("@#{accessor}", Kernel.send(type.to_s, val)) unless val.nil?
      end
    end
  end
end

相关问题