2008-11-13 3 views

ответ

719

Используйте ключевое слово defined? (documentation). Он вернет String с типом элемента или 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" 
+82

Стоит отметить, что переменная, которая установлена ​​в` nil` *, инициализируется *. – skalee 2011-02-16 13:18:34

+7

Если вы хотите установить переменную, если она не существует, и оставьте ее в покое, см. Ответ @ danmayer (с участием оператора `|| =`) ниже. – jrdioko 2011-07-12 21:29:23

+2

Это так рад. – Ziggy 2014-05-09 23:32:51

18

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

+0

+1 для `your_var.nil?` Потому что он возвращает true из false и гораздо лучше читать и писать, чем `defined? var`. Спасибо за это. – kakubei 2013-07-14 16:15:09

+25

`your_var.nil?` Приведет к ошибке: `undefined local variable или method your_var`, если не определено раньше ... – Gobol 2013-09-09 15:45:29

87

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

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

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

+7

Это очень идиоматический рубин тоже и очень типичный, кстати. – jrdioko 2011-07-12 21:28:33

+0

Спасибо за этот ввод! Вчера я был новичком в рубинах/рельсах и вчера вечером встретился с этим синтаксисом, ему было трудно понять, что это значит. Выглядит очень удобно! – 2011-11-07 10:35:35

+0

это не будет работать для определения констант – 2011-11-24 14:52:18

5

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

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 

Очевидно, что код окраски не нужно, просто хороший visualation в этом игрушечном примере.

67

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

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.

5

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

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

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

13

Try "если" вместо "если"

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 
8

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

2

Обратите внимание на различие между "определено" и " назначен».

$ ruby -e 'def f; if 1>2; x=99; end;p x, defined? x; end;f' 
nil 
"local-variable" 

x определено, даже если оно никогда не назначается!

0

Кроме того, вы можете проверить, если это определено в строке с помощью интерполяции, если код:

puts "Is array1 defined and what type is it? #{defined?(@array1)}" 

Система сообщит вам тип, если он определен. Если он не определен, он просто вернет предупреждение о том, что переменная не инициализирована.

Надеюсь, это поможет!:)

2

Как и многие другие примеры, вы действительно не нуждаетесь в логическом методе, чтобы сделать логический выбор в рубине. Было бы плохой формой, чтобы принуждать все к логическому, если вы действительно не нуждаетесь в логическом значении.

Но если вам абсолютно необходимо булево. Используйте! (удар), или «ложная ложность раскрывает правду».

› 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 
3

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

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

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

def method1 
    @x ||= method2 
end 

def method2 
    nil 
end 

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

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

Дайте определенному? метод прийти на помощь

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

Если вы не знали об этой уловке, а затем «ты собираешься нужно больше лодке».

2

Следует отметить, что использование defined, чтобы проверить, если определенное поле установлено в хэш может вести себя неожиданным:

var = {} 
if defined? var['unknown'] 
    puts 'this is unexpected' 
end 
# will output "this is unexpected" 

Синтаксис правильно здесь, но defined? var['unknown'] будет оцениваться в строку "method", так if блок будет выполнен

редактирования: правильное обозначение для проверки, если ключ существует в хэш будет:

if var.key?('unknown')