Проверка, определена ли переменная?
Как я могу проверить, определена ли переменная в Ruby? Есть ли isset
-тип доступный способ?
14 ответов
использовать defined?
ключевое слово (документация). Он вернет строку с типом элемента или nil
если он не существует.
>> a = 1
=> 1
>> defined? a
=> "local-variable"
>> defined? b
=> nil
>> defined? nil
=> "nil"
>> defined? String
=> "constant"
>> defined? 1
=> "expression"
как прокомментировал Скали: "стоит отметить, что переменная, которая установлена в ноль, инициализируется."
>> n = nil
>> defined? n
=> "local-variable"
это полезно, если вы хотите ничего не делать, если он существует, но создать его, если он не существует.
def get_var
@var ||= SomeClass.new()
end
это создает новый экземпляр только один раз. После этого он просто возвращается к Варе.
правильный синтаксис для приведенного выше утверждения:
if (defined?(var)).nil? # will now return true or false
print "var is not defined\n".color(:red)
else
print "var is defined\n".color(:green)
end
подставляя (var
) с переменной. Этот синтаксис возвращает значение true / false для оценки в операторе if.
defined?(your_var)
будет работать. В зависимости от того, что вы делаете, вы также можете сделать что-то вроде your_var.nil?
попробуйте "если" вместо "Если"
a = "apple"
# Note that b is not declared
c = nil
unless defined? a
puts "a is not defined"
end
unless defined? b
puts "b is not defined"
end
unless defined? c
puts "c is not defined"
end
можно попробовать:
unless defined?(var)
#ruby code goes here
end
=> true
потому что он возвращает boolean.
вот какой-то код, ничего ракетостроения, но он работает достаточно хорошо
require 'rubygems'
require 'rainbow'
if defined?(var).nil? # .nil? is optional but might make for clearer intent.
print "var is not defined\n".color(:red)
else
print "car is defined\n".color(:green)
end
ясно, что код окраски не нужен, просто хорошая визуализация в этом примере игрушки.
Это ключевой ответ: определяешь? метод. Принятый выше ответ прекрасно иллюстрирует это.
но есть акула, скрывающаяся под волнами...
рассмотрим этот тип общего рубинового шаблона:
def method1
@x ||= method2
end
def method2
nil
end
давайте остановимся и подумаем об этом на секунду. Метод 2 всегда возвращает nil. При первом вызове method1 переменная @x не задана - поэтому method2 будет запущен. и Метод 2 установит @x в ноль. Это прекрасно, и все хорошо. Но что происходит во второй раз, когда вы вызываете method1?
помните, что @x уже установлен в ноль. Но метод 2 все равно будет запущен снова? Если method2 является дорогостоящим предприятием, это может быть не то, что вы хотите.
дай определение? метод пришел на помощь
def method1
return @x if defined? @x
@x = method2
end
Если вы не знали об этом трюке, ну тогда "вам понадобится большая лодка".
как показывают многие другие примеры, вам на самом деле не нужно логическое значение из метода, чтобы сделать логический выбор в ruby. Было бы плохой формой принудить все к логическому, если вам действительно не нужно логическое.
но если вам абсолютно нужно логическое значение. Использовать !! (бах-бах) или "ложь, ложь раскрывает истину".
› irb
>> a = nil
=> nil
>> defined?(a)
=> "local-variable"
>> defined?(b)
=> nil
>> !!defined?(a)
=> true
>> !!defined?(b)
=> false
почему он обычно не платит за принуждение:
>> (!!defined?(a) ? "var is defined".colorize(:green) : "var is not defined".colorize(:red)) == (defined?(a) ? "var is defined".colorize(:green) : "var is not defined".colorize(:red))
=> true
вот пример, где это важно, потому что он опирается на неявное принуждение логическое значение для его строкового представления.
>> puts "var is defined? #{!!defined?(a)} vs #{defined?(a)}"
var is defined? true vs local-variable
=> nil
обратите внимание на различие между "определенными"и " назначенными".
$ ruby -e 'def f; if 1>2; x=99; end;p x, defined? x; end;f'
nil
"local-variable"
x определяется, даже если он никогда не назначается!
следует отметить, что использование defined
чтобы проверить, установлено ли определенное поле в хэше, может вести себя неожиданно:
var = {}
if defined? var['unknown']
puts 'this is unexpected'
end
# will output "this is unexpected"
синтаксис здесь, но defined? var['unknown']
будет оцениваться в строку "method"
, так что if
блок будет выполнен
edit: правильная нотация для проверки наличия ключа в хэше будет:
if var.key?('unknown')
кроме того, вы можете проверить, определено ли оно в строке с помощью интерполяции, если вы кодируете:
puts "Is array1 defined and what type is it? #{defined?(@array1)}"
система сообщит вам тип, если он определен. Если он не определен, он просто вернет предупреждение о том, что переменная не инициализирована.
надеюсь, что это помогает! :)
defined?
отлично, но если вы находитесь в среде Rails, вы также можете использовать try
, особенно в случаях, когда вы хотите проверить имя динамической переменной:
foo = 1
my_foo = "foo"
my_bar = "bar"
try(:foo) # => 1
try(:bar) # => nil
try(my_foo) # => 1
try(my_bar) # => nil