2010-05-08 130 views
0

所以,我希望能够拨打电话参数到Ruby中的实例方法

x = MyClass.new('good morning', 'good afternoon', 'good evening', 'good night', 
      ['hello', 'goodbye']) 

,将方法添加到其值的参数值的类。所以现在:

p x.methods #> [m_greeting, a_greeting, e_greeting, n_greeting, 
         r_greeting, ...] 

而且

p x.m_greeting #> "good morning" 
p x.r_greeting #> ['hello', 'goodbye'] 

我意识到这是某种变量是做什么的实例(和,如果我想他们一成不变我可以让他们冻结的常量),但原因超出我的控制范围,我需要改变方法。

谢谢!

BTW:我想

def initialize(*args) 
    i = 0 
    %w[m_a, m_b, m_c].each do |a| 
    self.class.send(:define_method, a.to_s, Proc.new { args[i] }) 
    i+=1 
    end 
end 

但是,最终让每一个方法的最后一个参数的值。

回答

1

你的最后一个循环将发送的最后一个参数重新定义方法为您的每个m_a, m_b, m_c尝试循环在指定参数和发送到索引的方法。

例如

def initialize(*args) 
    methods = %w[m_a m_b m_c] 
    args.each_with_index {|item,index| 
    self.class.send(:define_method, methods[index], lambda { item }) 
    } 
end 

each_with_index来自可枚举模块:http://ruby-doc.org/core/classes/Enumerable.html#M003137

2

我想这解决了这个问题:

def initialize(*args) 
    @args = args 
    %w[m_a m_b m_c].each_with_index do |a, i| 
    eval "def #{a}; @args[#{i}]; end" 
    end 
end 
+0

啊我在打字时发贴; \ – 2010-05-08 15:44:06

2

你可以做你想做的,就像这样:

class Foo 

    def initialize(*args) 
    methods = %w[m_greeting a_greeting e_greeting n_greeting r_greeting] 
    raise ArgumentError unless args.size == methods.size 
    args.zip(methods).each do |arg, method| 
     self.class.instance_eval do 
     define_method method do 
      arg 
     end 
     end 
    end 
    end 

end 

foo = Foo.new(1, 2, 3, 4, 5) 
p foo.m_greeting # => 1 
p foo.a_greeting # => 2 
p foo.e_greeting # => 3 
p foo.n_greeting # => 4 
p foo.r_greeting # => 5 

但是,这可能不是你要找的机器人:更多比少数位置参数可能使代码难以阅读。你可能会考虑使用OpenStruct。您将不得不写几乎没有代码,并且构造函数调用将更易于阅读:

require 'ostruct' 

class Foo < OpenStruct 
end 

foo = Foo.new(:m_greeting=>1, 
       :a_greeting=>2, 
       :e_greeting=>3, 
       :n_greeting=>4, 
       :r_greeting=>5) 
p foo.m_greeting # => 1 
p foo.a_greeting # => 2 
p foo.e_greeting # => 3 
p foo.n_greeting # => 4 
p foo.r_greeting # => 5 

不要冒汗可变性。如果您觉得需要编写代码来保护自己免受错误的侵害,请考虑编写单元测试。然后代码可以不受限制地进行各种检查和保护。