2013-06-23 48 views
0

我一直在尋找這個問題的答案一段時間,但我一直沒能找到一個我能夠理解和應用。如何使用字符串調用對象的方法?

我有一個包含三個實例變量的類:@brand@setup@year。我有一個包含在該類中的模塊,它有三種方法:print_brand(),print_setup()print_year(),它們只是打印分配給關聯變量的值。

我想從用戶獲取兩個字符串,並使用第一個作爲對象名稱,第二個作爲方法名稱。這就是我現在所擁有的:

class Bike 
    include(Printers) 
    def initialize(name, options = {}) 
    @name = name 
    @brand = options[:brand] 
    @setup = options[:setup] 
    @year = options[:year] 
    end 
end 

trance = Bike.new("trance x3", { 
    :brand => "giant", 
    :setup => "full sus", 
    :year => 2011 
    } 
) 
giro = Bike.new("giro", { 
    :brand => "bianchi", 
    :setup => "road", 
    :year => 2006 
    } 
) 
b2 = Bike.new("b2", { 
    :brand => "felt", 
    :setup => "tri", 
    :year => 2009 
    } 
) 

puts "Which bike do you want information on?" 
b = gets() 
b.chomp! 

puts "What information are you looking for?" 
i = gets() 
i.chomp! 

b.send(i) 

我缺少一些功能,從一個字符串對象名稱轉換b。例如,我希望用戶能夠輸入「恍惚」,然後輸入「print_year」並在屏幕上打印「2011」。我試圖在b上使用constantize,但這似乎不起作用。我收到錯誤:

in 'const_defined?': wrong constant name trance (NameError) 

有沒有其他想法?

+0

如果你說'b.send(我)',即假定'b '是一個擁有「i」作爲方法的對象。如果'b'是一個特定的自行車類型,那麼名稱是那種自行車類型的對象在哪裏?你的自行車類型是'Bike'的變量。這看起來像是一種基於查詢向用戶提供數據的複雜方式。 – lurker

+0

我建議使用數據庫,而不是嘗試將設置/選項存儲在RAM中。修改代碼以添加新自行車不是一個好主意;相反,你應該分開你的代碼和數據。用類似[Sequel](http://sequel.rubyforge.org/documentation.html)的東西來查看基於磁盤的SQLite數據庫。 –

回答

1

您應該將對象存儲在帶有key = name和value = object的散列映射中,然後使用b(name)從散列映射中檢索正確的對象。我仍然不確定你想用第二個輸入做什麼,我的猜測是這個答案也包含了這個。

h = Hash.new() 
h["trance x3"] = trance 
h["giro"] = giro 
... 
puts "Which bike do you want information on?" 
b = gets() 
b.chomp! 
user_bike = h[b] 

puts "What information are you looking for?" 
i = gets() 
i.chomp! 

user_bike.send(i) 
1

我會使用eval:

eval "#{ b }.#{ i }" 

我想你必須添加訪問器:

attr_accessor :brand, :setup, :year