2015-02-24 53 views
-1

我有一個字符串數組,代表現有的對象名稱。ruby​​ - 在動態命名對象上調用方法

JoesDev = Dev.new 
MarksDev = Dev.new 
SamsDev = Dev.new 

devices=['JoesDev', 'MarksDev', 'SamsDev' ] 

我想迭代設備數組,同時調用數組中的每個項目命名之後的對象的方法。

即;

JoesDev.method_name 
MarksDev.method_name 
SamsDev.method_name 

我該怎麼做?謝謝。

+1

無關,但我思你就會有一個更好的時間到底,如果你使用'Hash'代替,即'設備= {JoesDev:Dev.new,MarksDev:Dev.new,SamsDev: Dev.new}'。然後你可以像'devices ['JoesDev']。method_name'一樣訪問它們。 – Jon 2015-02-24 05:43:17

回答

0

您可以使用const_get method from Module讓Ruby返回給定名稱的常量。在你的情況下,它會返回Dev實例給你的任何設備名稱。

使用.each迭代的項目,你的代碼可能看起來像

devices.each do |device_name| 
    device = self.class.const_get(device_name) 
    device.method_name 
end 

# Which can be shortened to 
devices.each{ |dev| self.class.const_get(dev).method_name } 

不過,也有實現這種類型的事情更好的方法。最常用的方法是使用Hash。在你的榜樣,設備列表可能看起來像

devices = { 
    joe: Dev.new, 
    mark: Dev.new, 
    sam: Dev.new 
} 

然後,遍歷設備很簡單,只要

devices.each do |dev| 
    dev.method_name 
end 

# Or 
devices.each{ |dev| dev.method_name } 

附加:如果你想獲得一點點看上去,你可以使用block version of Hash::new來增加新設備非常簡單。

# Create the hash 
devices = Hash.new{ |hash, key| hash[key] = Dev.new } 

# Add the devices 
devices['joe'] 
devices['mark'] 
devices['sam'] 

這種哈希的作品完全一樣,上面顯示的一個,但會創建一個新條目,如果給定的密鑰不能在哈希被發現。這種設計的潛在問題在於,如果您輸入錯字,您可能會不小心添加新設備。例如

devices['jon'] # This would make a new Dev instance, which may be undesirable. 
+0

謝謝你jon!爲了清楚解釋。 – luckyme 2015-02-24 06:09:15

0

那麼一種方式肯定是使用eval,它允許你,如果他們的代碼執行任意的字符串的方法。

所以,在你的榜樣:

var_names.each{ |var_name| eval("#{var_name}.some_method") }

不用說,這是非常危險的,讓未經過濾的字符串作爲密碼,非常糟糕的事情™可能發生!

1
devices.each{|name| self.class.const_get(name).method_name} 
+1

這是對的,但它不是一個好的答案,除非它有一些上下文/解釋。 – Jon 2015-02-24 05:44:12

+3

@Jon我不會像給一個懶惰的人一個很好的答案,甚至不會打擾做正確的大寫和寫作像「thx」。 – sawa 2015-02-24 05:46:48

+0

你忘了發送嗎? – 2015-02-24 06:33:26