【问题标题】:Is there any built-in way to automatically enforce a type/class on an instance variable in Ruby?是否有任何内置方法可以自动对 Ruby 中的实例变量强制执行类型/类?
【发布时间】:2011-07-03 18:06:06
【问题描述】:

我正在使用 Ruby 和 Rails,所以任何 Rails 的 Ruby 扩展都应该没问题。

我想知道是否有一种方法可以有效地强制实例变量(而不是它们的 setter 和 getter)上的类型,这比手动定义它们更容易。

attr_accessor 等类方法不强制类型。例如,我注意到 Rails 的 ActiveRecord::Base 类对 setter 进行自动转换。它从数据库中得知一个特定的活动记录变量是一个整数,并用@record.integer_variable = '1' 设置它会自动转换参数并允许通过@record.integer_variable # => 1 进一步访问。

有没有办法利用这个?

我可以将自己的 getter 和 setter 编写为类方法,但如果更聪明的人已经完成了繁重的工作,我宁愿不必相信自己。

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    我不知道它是否已经有了一些东西,但你可以通过几行元编程来解决这个问题:

    module EnforceTypes
      def attr_accessor_of_type(name, type)
        send :define_method, name do
          instance_variable_get("@#{name}")
        end
        send :define_method, "#{name}=" do |v|
          raise ArgumentException unless v.is_a? type
          instance_variable_set("@#{name}", v)
        end
      end
    end
    

    用法:

    class MyClass
      extend EnforceTypes
    
      attr_accessor_of_type :some_string, String
    end
    

    当然,您可以通过更改第二个发出的方法、执行一些转换等来让它变得更聪明。

    这是一个很好的参考:http://www.raulparolari.com/Ruby2/attr_accessor

    请记住,几乎所有您可以通过手动复制和粘贴大量代码来完成的事情,都可以通过元编程来解决。

    【讨论】:

      猜你喜欢
      • 2018-08-20
      • 1970-01-01
      • 2010-11-22
      • 2012-01-07
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 2013-08-01
      相关资源
      最近更新 更多