Переменные доступа программно по имени в Ruby

Для меня эта проблема была вызвана использованием плагина prettier VSCode без наличия более красивого файла конфигурации в рабочей области.

Отключение плагина устранило проблему. Вероятно, он также был исправлен, полагаясь на более красивую конфигурацию.

24
задан Community 23 May 2017 в 10:31
поделиться

10 ответов

Что, если Вы изменяете к лучшему свою проблему? Вместо того, чтобы пытаться получить имена от переменных, получите переменные от имен:

["foo", "goo", "bar"].each { |param_name|
  param = eval(param_name)
  if param.class != Array
    puts "#{param_name} wasn't an Array. It was a/an #{param.class}"
    return "Error: #{param_name} wasn't an Array"
  end
  }

, Если был шанс одного переменные, не определяемые вообще (в противоположность тому, чтобы не быть массивом), Вы захотите добавить "спасательный ноль" до конца "параметрического усилителя =..." строка, чтобы помешать оценке выдавать исключение...

40
ответ дан glenn mcdonald 28 November 2019 в 22:14
поделиться

Необходимо повторно спроектировать решение. Даже если Вы могли делать это (Вы не можете), вопрос просто не имеет разумного ответа.

Воображают get_name метод.

a = 1
get_name(a)

Все могли, вероятно, согласиться, что это должно возвратиться

b = a
get_name(b)

, это должно возвратить 'b', или, или массив, содержащий обоих?

[b,a].each do |arg|
  get_name(arg)
end

это должно возвратить 'аргумент', 'b', или 'a'?

def do_stuff( arg )
  get_name(arg)
do
do_stuff(b)

это должно возвратить 'аргумент', 'b', или, или возможно массив всех их? Даже если бы это действительно возвращало массив, чем был бы порядок и как я буду знать, как интерпретировать результаты?

ответ на все вопросы выше, "Он зависит от конкретной вещи, которую я хочу в то время". Я не уверен, как Вы могли решить ту проблему для Ruby.

28
ответ дан Orion Edwards 28 November 2019 в 22:14
поделиться

Кажется, что Вы пытаетесь решить проблему, которая имеет намного более легкое решение..

, Почему не только хранят данные в хеше? Если Вы делаете..

data_container = {'foo' => ['goo', 'baz']}

.. это тогда совершенно тривиально для получения имени 'нечто'.

Однако Вы не дали контекста проблеме, таким образом, может быть причина, Вы не можете сделать этого..

[редактирование] После разъяснения, я вижу проблему, но я не думаю, что это - проблема.. С [нечто, панель, bla], это эквивалентно как высказывание ['content 1', 'content 2', 'etc']. Фактическое имя переменных (или скорее должен быть), совершенно не важный. Если название переменной важно, который является точно, почему хеши существуют.

проблема не с итерацией по [нечто, панель] и т.д., это - фундаментальная проблема с тем, как сервер SOAP является returing данные, и/или как Вы пытаетесь использовать его.

решение, я сказал бы, состоит в том, чтобы или сделать хеши возврата сервера SOAP, или, так как Вы знаете, там всегда будет тремя элементами, можете Вы не делать чего-то как..

{"foo" => foo, "goo" => goo, "bar"=>bar}.each do |param_name, param|
      if param.class != Array
        puts "#{param_name} wasn't an Array. It was a/an #{param.class}"
        puts "Error: #{param_name} wasn't an Array"
      end
end
8
ответ дан dbr 28 November 2019 в 22:14
поделиться

Хорошо, это ДЕЙСТВИТЕЛЬНО работает в методах экземпляра также и, на основе Вашего конкретного требования (тот, который Вы вставляете комментарий), Вы могли сделать это:

local_variables.each do |var|
  puts var if (eval(var).class != Fixnum)
end

Просто замена Fixnum с Вашей проверкой определенного типа.

5
ответ дан Brian Warshaw 28 November 2019 в 22:14
поделиться

Основываясь joshmsmoore, что-то вроде этого, вероятно, сделало бы это:

# Returns the first instance variable whose value == x
# Returns nil if no name maps to the given value
def instance_variable_name_for(x)
  self.instance_variables.find do |var|
    x == self.instance_variable_get(var)
  end
end
2
ответ дан Community 28 November 2019 в 22:14
поделиться

Я не знаю ни о каком способе получить имя локальной переменной. Но, можно использовать instance_variables метод, это возвратит массив всех имен переменной экземпляра в объекте.

Простой вызов:

object.instance_variables

или

self.instance_variables

для получения массива всех имен переменной экземпляра.

2
ответ дан Josh Moore 28 November 2019 в 22:14
поделиться

Существует Kernel::local_variables, но я не уверен, что это будет работать на локальный Вар метода, и я не знаю, что можно управлять им таким способом как, чтобы сделать то, чего Вы хотите достигнуть.

2
ответ дан Brian Warshaw 28 November 2019 в 22:14
поделиться

Вы не можете, необходимо пойти назад к исходной точке и повторно спроектировать решение.

1
ответ дан pauliephonic 28 November 2019 в 22:14
поделиться

Нечто является только местоположением для содержания указателя на данные. Данные не знают о какой точки в нем. В системах Smalltalk Вы могли попросить у VM всех указателей на объект, но это только получит Вас объект, который содержал переменную нечто, не само нечто. Нет никакого реального способа сослаться на vaiable в Ruby. Как упомянуто одним ответом можно все еще поместить тег в данные, что ссылки, куда это прибыло из или такой, но обычно который не является хорошим подходом к большинству проблем. Можно использовать хеш, чтобы получить значения во-первых или использовать хеш для передачи циклу, таким образом, Вы знаете имя аргумента целей проверки как в ответе DBR.

1
ответ дан Michael Latta 28 November 2019 в 22:14
поделиться

Самая близкая вещь к реальному ответу Вам вопрос состоит в том, чтобы использовать Счетный метод each_with_index вместо каждого, таким образом:

my_array = [foo, baz, bar]
my_array.each_with_index do |item, index|
  if item.class != Array
    puts "#{my_array[index]} wasn't an Array. It was a/an #{item.class}"
  end
end

я удалил оператор возврата из блока, Вы были передающими к each/each_with_index, потому что это ничто не/означало. Каждый и each_with_index оба возвращают массив, на который они воздействовали.

существует также что-то об объеме в блоках, которые стоит отметить здесь: при определении переменной за пределами блока это будет доступно в нем. Другими словами, Вы могли обратиться к нечто, панели и baz непосредственно в блоке. Обратное неверно: переменные, которые Вы создаете впервые в блоке, не будут доступны за пределами него.

Наконец,/заканчивать синтаксис предпочтен для многострочных блоков, но это - просто вопрос стиля, хотя это универсально в коде Ruby любого недавнего года изготовления вина.

1
ответ дан Greg Borenstein 28 November 2019 в 22:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: