Проверка, если переменная определена? - PullRequest
563 голосов
/ 14 ноября 2008

Как я могу проверить, определена ли переменная в Ruby? Есть ли метод isset типа?

Ответы [ 14 ]

771 голосов
/ 14 ноября 2008

Используйте ключевое слово defined? ( документация ). Он вернет строку с типом элемента или nil, если он не существует.

>> a = 1
 => 1
>> defined? a
 => "local-variable"
>> defined? b
 => nil
>> defined? nil
 => "nil"
>> defined? String
 => "constant"
>> defined? 1
 => "expression"

Как отметил Скали: «Стоит отметить, что переменная, для которой установлено значение nil, инициализирована».

>> n = nil  
>> defined? n
 => "local-variable"
91 голосов
/ 14 ноября 2008

Это полезно, если вы хотите ничего не делать, если оно существует, но создавать его, если оно не существует.

def get_var
  @var ||= SomeClass.new()
end

Это создает новый экземпляр только один раз. После этого он просто продолжает возвращать переменную.

70 голосов
/ 27 мая 2011

Правильный синтаксис для вышеприведенного оператора:

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.

18 голосов
/ 14 ноября 2008

defined?(your_var) будет работать. В зависимости от того, что вы делаете, вы также можете сделать что-то вроде your_var.nil?

15 голосов
/ 07 апреля 2012

Попробуйте "если" вместо "если"

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
9 голосов
/ 26 апреля 2013

Использование defined? YourVariable
Держи это просто глупо ..;)

7 голосов
/ 16 сентября 2010

Вот некоторый код, ничего ракетостроения, но он работает достаточно хорошо

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

Ясно, что код раскраски не нужен, просто приятная визуализация в этом примере с игрушкой.

6 голосов
/ 08 июля 2017

ПРЕДУПРЕЖДЕНИЕ Re: Общий шаблон Ruby

Это ключевой ответ: метод defined?. Принятый ответ выше прекрасно это иллюстрирует.

Но под волнами скрывается акула ...

Рассмотрим этот тип общего шаблона рубина:

 def method1
    @x ||= method2
 end

 def method2
    nil
 end

method2 всегда возвращает nil. При первом вызове method1 переменная @x не устанавливается - поэтому будет запущен method2. и method2 установит @x в nil. Это хорошо, и все хорошо. Но что происходит во второй раз, когда вы звоните method1?

Помните, @x уже был установлен в ноль. But method2 все равно снова будет запущен !! Если method2 является дорогостоящим мероприятием, возможно, это не то, что вам нужно.

Пусть на помощь придет метод defined? - с этим решением этот конкретный случай обрабатывается - используйте следующее:

  def method1
    return @x if defined? @x
    @x = method2
  end

Дьявол кроется в деталях: но вы можете избежать этой скрывающейся акулы с помощью метода defined?.

5 голосов
/ 16 марта 2012

Вы можете попробовать:

unless defined?(var)
  #ruby code goes here
end
=> true

Потому что он возвращает логическое значение.

3 голосов
/ 15 августа 2017

Следует отметить, что использование 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')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...