2010-05-08 131 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 

不要冒汗可變性。如果您覺得需要編寫代碼來保護自己免受錯誤的侵害,請考慮編寫單元測試。然後代碼可以不受限制地進行各種檢查和保護。