2011-12-24 93 views
-1

我有以下兩個變量:與名稱設定變量A存儲在變量B

a = 1; 
b = 'a'; 

我希望能夠做

SOMETYPEOFEVALUATION(b) = 2; 

使變量a的值現在設置到2

a # => 2 

這可能嗎?

具體來說,我正在使用Facebook API。每個對象都有各種不同的連接(朋友,喜歡,電影等)。我有一個解析器類,用於存儲所有這些連接的最後一次調用Facebook API的狀態。這些狀態都被命名爲與您必須調用以更新它們的GET相對應的狀態。

例如,要更新音樂連接,您使用https://graph.facebook.com/me/music?access_token= ...我將結果存儲在一個名爲updated_music變量。對於書籍,其updated_books。如果我創建了所有這些連接類型名稱的列表,我最好想做這樣的事情。

def update_all 
    connection_list.each do |connection_name| 
    updated_SomeTypeOfEvalAndConcatenation(connection_name) = CallToAPI("https://graph.facebook.com/me/#{connection_name}?access_token=...") 
    end 
end 

很新的兩個軌和StackOverflow上所以請讓我知道是否有更好的方式來遵循任何約定。

試過以下。

class FacebookParser 

attr_accessor :last_albums_json,   

    def update_parser_vars(service) 
    handler = FacebookAPIHandler.new 
    connections_type_list = ['albums'] 
    connections_type_list.each do |connection_name| 
     eval "self.last_#{connection_name}_json = handler.access_api_by_content_type(service, #{connection_name})['data']" 
    end 
    #self.last_albums_json = handler.access_api_by_content_type(service, 'albums')['data'] 
    end 


end 

而且我得到這個錯誤

undefined local variable or method `albums' for #<FacebookParser:0xaa7d12c> 

工作正常,當我使用的是被註釋掉線。

回答

1

怎麼樣

eval "#{b}=2" 

,並用實例變量,你也可以做instance_variable_set("@name", value)

編輯:

你也可以使用send方法,如果您有定義一個setter(和你)試試這個:

class FacebookParser 
    attr_accessor :last_albums_json,   

    def update_parser_vars(service) 
    handler = FacebookAPIHandler.new 
    connections_type_list = ['albums'] 
    connections_type_list.each do |connection_name| 
     send("last_#{connection_name}_json=", 
     handler.access_api_by_content_type(
      service, connection_name)['data'])) 
    end 
    end 
end 

你的o問題riginal代碼是

eval ".... handler.access_api_by_content_type(service, #{connection_name})" 

將執行

... handler.access_api_by_content_type(service, albums) 
# instead of 
... handler.access_api_by_content_type(service, 'albums') 

,所以你必須寫

eval ".... handler.access_api_by_content_type(service, '#{connection_name}')" <- the quotes! 

這就是爲什麼人們通常會避免使用eval - 這是很容易做到這種錯誤

+0

'instance_variable_set',不'set_instance_variable' – steenslag 2011-12-24 21:29:00

+0

沒有工作。請參閱上面的編輯 – user1114840 2011-12-24 23:54:48

+0

更新,並btw你*可以*在你的代碼中使用instance_variable_set,因爲attr_accessor基本上是生成getter/setter例如變量 – keymone 2011-12-25 11:05:24

3

像這樣改變一個不相關的變量有點代碼味道;大多數程序員都不喜歡它,當一個變量奇蹟般地改變值時,至少不是不在一個封閉類中。

在這種簡單的例子,它的更常見的說法:

a=something(b) 

或者,如果是一個比較複雜的事情,使它成爲一個類:

class Foo 
    attr_accessor :a 

    def initialize(value) 
    @a = value 
    end 

    def transform(value) 
    @a = "new value: #{value}" 
    end 
end 

baz = "something" 
bar = Foo.new(2) 
bar.a 
=> 2 
bar.transform(baz) 
bar.a 
=> "new value: something" 

因此,儘管第二個例子中的變化一個內部變量但不通過訪問器,至少它是具有有限API的封裝對象的一部分。

更新嗯,我認爲問題是怎麼辦,像php的variable variables。正如穆建議,如果你想這樣做,你可能做錯了事情......這是一個永遠不會想到的概念。使用類或哈希等。

+0

在這種情況下看不到如何做一個有用的類。我可以把所有的變量放到一個新的類中,比如說「ParserVars」,但是它仍然需要一組if語句來匹配傳入的參數和其中一個變量。要清楚,必須使用所有這些if語句是我試圖避免的。 – user1114840 2011-12-25 12:06:35

+0

@ user1114840只是看看你的變量,你可以立即說有太多東西正在進行 - * last * _ * albums * _ * json *,檢查你是否可以將它重構成更簡潔的代碼,比如只有'albums'然後你的對象會提供'albums.last',然後通過'albums.last.to_json'將它轉換成json - 這就是很多的可重用性! – keymone 2011-12-25 19:20:44

0

這些東西通常不是在Ruby中使用局部變量和它們的名字來完成的。一個通常的辦法可能包括散列和符號:

data = Hash.new 
data[:a] = 1 # a = 1 
b = :a  # b = 'a' 

然後,後來

data[b] = 2 # SOMETYPEOFEVALUATION(b) = 2 
data[:a]  # => 2