Setting variable A with name stored in variable B

I have the following two variables:

a = 1;
b = 'a';

I want to be able to do

SOMETYPEOFEVALUATION(b) = 2;

so that the value of variable a is now set to 2 .

a # => 2 

Is this possible?

Specifically, I am working with the Facebook API. Each object has a variety of different connections (friends, likes, movies, etc). I have a parser class that stores the state of the last call to the Facebook API for all of these connections. These states are all named corresponding to the the GET you have to call in order to update them.

For example, to update the Music connection, you use https://graph.facebook.com/me/music?access_token=... I store the result in a variable called updated_music. For books, its updated_books. If I created a list of all these connection type names, I ideally want to do something like this.

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

Very new to both Rails and StackOverflow so please let me know if there is a better way to follow any conventions.

Tried the below.

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

And I get this error

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

Works fine when I use line that is commented out.


how about

eval "#{b}=2"

and with instance variables you can also do instance_variable_set("@name", value)

EDIT:

you can also use send method if you have a setter defined(and you have), try this:

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

problem with your original code is that

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

would execute

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

so you had to write

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

this is why people usually avoid using eval - it's easy to do this kind of mistakes


Changing an unrelated variable like that is a bit of a code smell; Most programmers don't like it when a variable magically changes value, at least not without being inside an enclosing class.

In that simple example, it's much more common to say:

a=something(b)

Or if a is a more complex thing, make it a class:

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"

So while the second example changes an internal variable but not through the accessor, at least it is part of an encapsulated object with a limited API.

Update Ah, I think the question is how do do like php's variable variables. As mu suggests, if you want to do this, you are probably doing the wrong thing... it's a concept that should never have been thought of. Use classes or hashes or something.


These sort of things are not usually done using local variables and their names in Ruby. A usual approach could include hashes and symbols:

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

and then, later

data[b] = 2  # SOMETYPEOFEVALUATION(b) = 2
data[:a]     # => 2
链接地址: http://www.djcxy.com/p/25766.html

上一篇: 方法用例太复杂?

下一篇: 设置名称存储在变量B中的变量A.