변수가 정의되어 있는지 확인 하시겠습니까?


581

변수가 Ruby에 정의되어 있는지 어떻게 확인할 수 있습니까? 있습니까 isset타입의 방법은 가능?

답변:


791

defined?키워드 ( documentation )를 사용하십시오 . 항목의 종류가 있거나 nil존재하지 않는 경우 String을 반환 합니다.

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

skalee는 다음과 같이 말했습니다 : "nil로 설정된 변수가 초기화되었다는 점에 주목할 가치가 있습니다."

>> n = nil  
>> defined? n
 => "local-variable"

92
로 설정된 변수 nil 초기화 되었음을 주목할 가치 있습니다.
skalee

7
변수가 존재하지 않는 경우 변수를 설정하고 존재하는 경우 그대로 두려면 아래의 @ danmayer 's answer ( ||=연산자 포함)를 참조하십시오.
jrdioko

2
조건이 충족되지 않는 if-block defined?에서 변수를 정의하면 해당 블록 내에 정의 된 변수에 대해 true를 반환합니다.
elsurudo

1
defined?부울을 반환 하는 것과 같은 방법이 있습니까?
stevec

true / false를 반환하려면!!defined?(object_name)
stevec

91

존재하는 경우 아무것도하지 않고 존재하지 않는 경우 생성하려는 경우에 유용합니다.

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

새 인스턴스를 한 번만 만듭니다. 그 후에는 var를 계속 반환합니다.


9
그건 그렇고 아주 관용적 인 루비이기도합니다.
jrdioko

38
||=혼란의 고통을 느끼지 않도록 부울 값과 함께 사용하지 마십시오 .
Andrew Marshall

6
@AndrewMarshall는 말과 함께 반환 할 수 있습니다 아무것도이 관용구를 방지 nil뿐만 아니라 당신이하지 않으면 정말 이는 반환하지 않습니다 때 호출 식마다 시간을 평가하려는nil
nzifnab

1
당신이하면 된다 : 부울 작업, 변수가 명시 적으로 false로 설정되지 않은 경우 디폴트 값이 true가되고 싶어요, 당신은이 건설 사용할 수 있습니다 var = (var or var.nil?)
토니 지토

1
@ArnaudMeuret 실제로는 아닙니다. 동일하게 보이지는 않지만 해당 질문에 대한 답변을 읽을 가치가 있습니다.
기금 모니카의 소송

70

위 문장의 올바른 구문은 다음과 같습니다.

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변수를 ( )로 바꾸십시오. 이 구문은 if 문에서 평가할 true / false 값을 반환합니다.


11
테스트에서 사용될 때 nil이 거짓으로 평가 될 때 필요하지 않습니다
Jerome

왜 안돼 defined?(var) == nil?
vol7ron

@ vol7ron-완벽하게 유효한 구문입니다. 전화를하는 .nil?것은 그들이 말하는 것처럼 관용적입니다. nil비교 연산자를 사용하는 것 보다 객체를 요청하는 것이 더 "객체 지향적" 입니다. 읽기도 어렵지 않으므로 더 많은 제품을 배송하는 데 도움이되는 것을 사용하십시오.
juanpaco

당신은 어느 말을 언급합니까?!? 답변을 다른 것에 대한 주석으로 사용하지 마십시오.
Arnaud Meuret

18

defined?(your_var)작동합니다. 하고있는 일에 따라 다음과 같은 일을 할 수도 있습니다your_var.nil?


+1 your_var.nil?은 false를 true로 반환하고보다 읽고 쓰는 것이 훨씬 좋습니다 defined? var. 고마워
kakubei

28
your_var.nil?오류가 발생합니다 : undefined local variable or method your_var전에 정의되지 않은 경우 ...
Gobol

16

"if"대신 "unless"를 시도하십시오

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

이 답변은 다른 답변에서 언급하지 않은 내용을 추가합니까?
앤드류 그림

2
그것은 하나의 유용한 방법으로 질문에 매우 잘 대답합니다. 그렇지 않습니까?

2
루비 스타일 가이드에 따르면 "부정적인 조건이 아닌 한 선호하지 않는다
ChrisPhoenix

9

사용 defined? YourVariable
이 간단 바보 유지 ..;)


8

여기에 몇 가지 코드가 있지만 로켓 과학은 없지만 잘 작동합니다.

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

분명히이 색칠 예제는 필요하지 않으며이 장난감 예제에서 멋진 시각화 일뿐입니다.


아마도 nil?선택 사항 이기 때문일 것 입니다.
제임스

8

경고 Re : 일반적인 루비 패턴

이것이 핵심 답입니다 : defined?방법. 위의 대답은 이것을 완벽하게 보여줍니다.

그러나 파도 아래에 숨어있는 상어가 있습니다 ...

이 유형의 일반적인 루비 패턴을 고려하십시오.

 def method1
    @x ||= method2
 end

 def method2
    nil
 end

method2항상을 반환합니다 nil. 을 처음 호출 method1하면 @x변수가 설정되지 않으므로 method2실행됩니다. 로 method2설정 @x됩니다 nil. 괜찮습니다. 하지만 두 번째로 전화하면 어떻게됩니까 method1?

@x는 이미 nil로 설정되어 있습니다. But method2여전히 다시 실행됩니다 !! method2가 비용이 많이 드는 작업 인 경우 원하는 것이 아닐 수도 있습니다.

defined?방법으로 특정 방법을 처리 하여 방법을 구하십시오. 다음을 사용하십시오.

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

악마는 세부 사항에 있지만 defined?방법으로 숨어있는 상어를 피할 수 있습니다 .


당신은 전적으로 맞습니다. 특정 경고를 강조해 주셔서 감사합니다
Kulgar

5

당신은 시도 할 수 있습니다:

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

부울을 반환하기 때문입니다.


SyntaxError: compile error (irb):2: syntax error, unexpected $end, expecting kEND
Andrew Grimm

unless진술 을 사용하는 것은 지나치게 복잡해 보인다
johannes

5

다른 많은 예제에서 보듯이 루비에서 논리적으로 선택하기 위해 메소드에서 부울이 실제로 필요하지 않습니다. 실제로 부울이 필요하지 않으면 모든 것을 부울로 강제 변환하는 것은 좋지 않은 형태입니다.

그러나 부울이 절대적으로 필요한 경우. 사용하다 !! (뱅뱅) 또는 "거짓 거짓은 진실을 드러낸다".

 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

defined특정 필드가 해시에 설정되어 있는지 확인 하는 데 사용 하면 예기치 않은 동작이 발생할 수 있습니다.

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

구문은 여기에서는 정확하지만 defined? var['unknown']string으로 평가 "method"되므로 if블록이 실행됩니다.

편집 : 키가 해시에 있는지 확인하는 올바른 표기법은 다음과 같습니다.

if var.key?('unknown')

2

"정의 된"과 "할당 된"의 차이점에 유의하십시오.

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

x는 할당되지 않아도 정의됩니다!


이것은 내가 방금 만난 것입니다. 나는 기대 NameError Exception: undefined local variable or method하고 있었고 변수의 유일한 할당 / 멘션이 적중되지 않은 if 블록에있을 때 혼란 스러웠다.
Paul Pettengill

0

또한 코드를 작성하는 경우 보간을 통해 문자열에 정의되어 있는지 확인할 수 있습니다.

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

유형이 정의되어 있으면 시스템에서 알려줍니다. 정의되어 있지 않으면 변수가 초기화되지 않았다는 경고를 반환합니다.

도움이 되었기를 바랍니다! :)


0

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.