Установка переменной A с именем, хранящимся в переменной B - PullRequest
0 голосов
/ 25 декабря 2011

У меня есть следующие две переменные:

a = 1;
b = 'a';

Я хочу быть в состоянии сделать

SOMETYPEOFEVALUATION(b) = 2;

, так что значение переменной a теперь установлено на 2.

a # => 2 

Возможно ли это?

В частности, я работаю с Facebook API. Каждый объект имеет различные связи (друзья, лайки, фильмы и т. Д.). У меня есть класс анализатора, который хранит состояние последнего вызова API Facebook для всех этих соединений. Эти состояния называются в соответствии с 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>

Работает нормально, когда я использую закомментированную строку.

Ответы [ 3 ]

3 голосов
/ 25 декабря 2011

Изменение несвязанной переменной, вроде этого, немного пахнет кодом;Большинству программистов не нравится, когда переменная волшебным образом меняет значение, по крайней мере, не находясь внутри окружающего класса.

В этом простом примере гораздо чаще говорят:

a=something(b)

Или, если a - более сложная вещь, сделайте ее классом:

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 .Как говорит мю, если вы хотите сделать это, вы, вероятно, делаете не то, что нужно ... это концепция, о которой никогда не следует думать.Используйте классы или хэши или что-то в этом роде.

1 голос
/ 25 декабря 2011

как насчет

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

проблема с вашим исходным кодом в том, что

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 голосов
/ 25 декабря 2011

Подобные вещи обычно не выполняются с использованием локальных переменных и их имен в Ruby.Обычный подход может включать хеши и символы:

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

, а затем, позже

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