Имейте в виду, что независимо от сценария причина всегда одинакова в .NET:
Вы пытаетесь использовать ссылочную переменную, значение которой
Nothing
/null
. Если для ссылочной переменной значениеNothing
/null
, это означает, что на самом деле оно не содержит ссылку на экземпляр любого объекта, который существует в куче.Вы либо никогда не присваивали какую-либо переменную, никогда не создавали экземпляр значения, присвоенного переменной, или вы вручную устанавливали переменную, равную
blockquote>Nothing
/null
, или вы вызывали функцию, которая установите для этой переменной значениеNothing
/null
.
myvar = ENV['MY_VAR'] || 'foobar'
N.B. Это немного некорректно (если хэш может содержать значение nil
), но поскольку ENV
содержит только строки, это, вероятно, достаточно хорошо.
hash.fetch(key) { default_value }
Вернет значение, если оно существует, и вернет default_value
, если ключ не существует.
Хотя это не относится к конкретному примеру, который вы дали, поскольку вы действительно спрашиваете о хэш-ключах, а не о переменных, Ruby действительно дает возможность проверить определение переменной. Используйте ключевое слово defined?
(это не метод, а ключевое слово, так как для интерпретатора требуется специальная обработка):
a = 1
defined? a
#=> "local-variable"
@a = 2
defined? @a
#=> "instance-variable"
@@a = 3
defined? @@a
#=> "class-variable"
defined? blahblahblah
#=> nil
Следовательно, вы можете сделать:
var = defined?(var) ? var : "default value here"
Насколько я знаю, это единственный способ, отличный от уродливого блока begin
/ rescue
/ end
, чтобы определить переменную так, как вы просите, не рискуя NameError. Как я уже сказал, это не относится к хэшам с:
hash = {?a => 2, ?b => 3}
defined? hash[?c]
#=> "method"
i.e. вы проверяете, что метод []
определен, а не пара ключей / значений, которые вы используете для доступа.
myvar = ENV.fetch('MY_VAR') { 'foobar' }
'foobar'
является значением по умолчанию, если ENV['MY_VAR']
не установлен.
myvar = ENV['MY_VAR'].is_set? ? ENV['MY_VAR'] : 'foobar'
Таким образом вы сохраняете .is_set? метод.
Самый надежный способ для общего хэша - спросить, есть ли у него ключ:
myvar = h.has_key?('MY_VAR') ? h['MY_VAR'] : 'default'
Если вам не нужны значения nil
или false
(т.е. вы хотите обрабатывать их так же, как «не существует»), тогда подход undur_gongor хорош (это также должно быть хорошо, когда h
есть ENV
):
myvar = h['MY_VAR'] || 'foobar'
И если вы хотите разрешить nil
, чтобы быть в вашем хэше, но притворяться, что его нет (т.е. значение nil
совпадает с «не существует»), позволяя false
в вашем хэше:
myvar = h['MY_VAR'].nil?? 'foobar' : h['MY_VAR']
In конец действительно зависит от вашего точного намерения, и вы должны выбрать подход, который соответствует вашим намерениям. Выбор между if/else/end
и ? :
, конечно, является вопросом вкуса и «кратким», не означает «наименьшее количество символов», поэтому не стесняйтесь использовать тройной или if
блок по желанию.