【问题标题】:Ruby: adding instance variables to an objectRuby:向对象添加实例变量
【发布时间】:2012-05-18 12:20:27
【问题描述】:

如何将一堆实例变量从一个对象添加到另一个对象?

例如,假设您拥有基础机器人并且可以使用附加组件对其进行自定义。

类机器人 定义初始化 @name = "简单机器人" @power = nil #没有电源 @速度 = 无 # 更多属性 结尾 def add_attributes(插件) @power = addon.power @speed = addon.speed #插件具有的其余属性 结尾 结尾

我想重写 add_attributes 方法来简单地迭代每个插件的属性,而不是一个一个地写它们,因为可能有几十个属性。

一些插件可能有 Robot 没有的实例变量,我也想将它们添加到 Robot。就像动态创建实例变量一样?

【问题讨论】:

    标签: ruby


    【解决方案1】:

    这取决于你所说的“属性”; Ruby 没有直接的概念,但您可以将实例变量从一个对象复制到另一个对象:

    def add_attributes(addon)
      addon.instance_variables.each do |x|
        self.instance_variable_set(addon.instance_variable_get(x))
      end      
    end
    

    [编辑]注意answer by @HolgerJust也是一个很好的解决方案。

    【讨论】:

    • 我真的不喜欢像这样窥视插件的实例变量。插件应该真正提供一种获取其属性列表的统一方法,然后可以在其上调用该方法。 (当然,根据给定的信息,您所拥有的可能是最好的解决方案。)
    【解决方案2】:

    您可以摆脱实例变量并改用单个哈希值。这具有免费枚举器和干净界面的优势,可以从一个方便的地方访问机器人的所有功能。

    它还避免了与实例内部变量混淆。它们通常是内部的,用于大量的东西。如果要公开功能,则应使用公共方法。弄乱内部状态至少是糟糕的设计,并且很可能会在以后导致很多悲伤。一般来说,最好尽可能避免元编程。

    class Robot
      attr_reader :features
    
      def initialize
        @features = {}
        @features[:name] = "simple robot"
        @features[:power] = nil #no power
        @features[:speed] = nil
      end
    
      def add_attributes(addon)
        @features.merge! addon.features
      end
    end
    

    【讨论】:

    • 使用 Hash#merge 而不是迭代 addon 参数将清理 add_attributes 方法。
    【解决方案3】:

    您可以使用灵活的 gem[0],让您无需编写太多代码即可动态创建实例变量。 做吧

    class SomeClass
      include Flexible
    end
    sc = SomeClass.new
    sc.my_variable_name = 1 # or any other value
    

    [0]https://github.com/matthiasbeyer/flexible

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-14
      • 2010-12-25
      • 2015-02-08
      • 2018-07-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多