2011-12-24 11 views
-1

私は、次の2つの変数を持っている:設定変数A

私が行うことができるようにしたい
a = 1; 
b = 'a'; 

変数aの値は、現在設定されているので、

SOMETYPEOFEVALUATION(b) = 2; 

2

a # => 2 

これは可能ですか?

具体的には、Facebook APIを使用しています。各オブジェクトにはさまざまな異なる接続(友人、好きな人、映画など)があります。私はこれらすべての接続のFacebook APIへの最後の呼び出しの状態を保存するパーサークラスを持っています。これらの状態は、それらを更新するために呼び出さなければならないGETに対応してすべて名前が付けられます。

たとえば、Music接続を更新するには、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 

Railsと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)

EDIT:

あなたが定義されたセッターを持っている(とあなたが持っている)場合にもsendメソッドを使用することができ、試してみてください:

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 

あなたの問題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を使用しないよう、なぜこれが

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

書かなければならなかった実行ということである - それはミスのこの種を行うのは簡単です

+0

'instance_variable_set'、ない' set_instance_variable' – steenslag

+0

は動作しませんでした。 – user1114840

+0

上記の編集更新を参照してください、とattr_accessorは、基本的には、たとえば変数 – keymone

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" 

だから、2番目の例では、変化しながら、内部変数ではなくアクセッサを介さずに、少なくとも限定されたAPIを持つカプセル化オブジェクトの一部です。

更新ああ、私はどのようにPHPのvariable variablesが好きなのでしょうかと思う。ミューが示唆するように、あなたがこれをやりたいのであれば、あなたはおそらく間違ったことをやっているのです。それは決して考えられてはいけない概念です。クラスやハッシュなどを使用します。

+0

動作し、このような状況で有用なクラスを作成する方法を参照してくださいしないでください。私はすべての変数を新しいクラス、例えば "ParserVars"に入れることができますが、渡された引数を変数の1つと一致させるためには、内部にif文のセットが必要です。明らかにするには、それらのif文のすべてを使用する必要がありますが、私が避けようとしているものです。 – user1114840

+0

@ user1114840あなたの変数を見てみると、あまりにも多くのことが起こっていると即座に言うことができます - * last * _ * albums * _ * json *、あなたがそれをリファクタリングできるかどうかチェックします。あなたのオブジェクトは 'albums.last'を提供し、' albums.last.to_json'を実行することによってjsonに変換することができます - それはすぐに再利用可能です! – keymone

0

これらのことは通常、Rubyでローカル変数とその名前を使用して行われません。通常のアプローチは、ハッシュと記号を含めることができます

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

してから、後で

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