2012-05-26 2 views
2

IRB는 Ruby에서 놀고 테스트하는 좋은 방법입니다. 그것은 다음과 같이 스크립트를 사용하여 일부 설정을 할 수도 있습니다 :이 일을 할 때 내가 불분명 해요새 IRB 세션은 어떻게 가변 범위를 갖습니까?

require 'irb' 

class Pirate 
    def greet 
    puts "Arrrrr, nice to meet ya" 
    end 
end 

IRB.start # You can now instantiate Pirate in IRB 

한 가지 그러나 변수 범위입니다. 내가 IRB.start 전에이 줄을 추가하는 경우 :

smithy  = Pirate.new 
@blackbard = Pirate.new 

... @blackbeard은 IRB에서 사용할 수 있지만 smithy를 참조하면 undefined local variable or method 'smithy' for main:Object을 얻을 것이다.

왜? 코드를 평가하는 데 사용됩니다

답변

6

Bindingirb/workspace.rb:51에서 설정 (여기 루비 1.9.3에 35410 REV 말하는 겁니다) :

@binding = eval("def irb_binding; binding; end; irb_binding", 
       TOPLEVEL_BINDING, 
       __FILE__, 
       __LINE__ - 3) 

즉, 그 같은에서 IRB 세션 실행 컨텍스트를 최상위 메서드 내부의 코드로 사용합니다. 관찰 :

puts "Outer object ID: %d" % self.object_id 
puts "Outer binding: " + binding.inspect 
smithy  = Pirate.new 
@blackbard = Pirate.new 

def test 
    puts "Inner object ID: %d" % self.object_id 
    puts "Inner binding: " + binding.inspect 
    p @blackbard 
    p smithy 
end 
test 

출력 : 객체 컨텍스트 (self)이 내부 및 외부에 동일 기능을인지

Outer object ID: 13230960 
Outer binding: #<Binding:0x00000001c9aee0> 
Inner object ID: 13230960 
Inner binding: #<Binding:0x00000001c9acd8> 
#<Pirate:0x00000001c9ada0> 
/test.rb:18:in `test': undefined local variable or method `smithy' for main:Object (NameError) 
    ... 

참고. 모든 최상위 메서드가 전역 main 개체에 추가되기 때문입니다.

또한 메서드 내부와 외부의 바인딩이 다릅니다. Ruby에서 모든 메소드는 고유 한 이름 범위를가집니다. 따라서 인스턴스 변수에 액세스 할 수있는 동안 IRB 내부에서 로컬 이름에 액세스 할 수 없습니다.

솔직히 말해서 IRB는 영광스러운 루비 소프트웨어가 아닙니다.

require 'pry' 
binding.pry 

을 그리고 현재의 지역 변수에 액세스 할 수있는 세션을 가지고 : 나는 보통 당신이 단지 할 수있는 사용, 이런 종류의 물건에 대한 Pry를 사용합니다.

+0

매우 통찰력있는 내용입니다. – Renra

+0

+1 Pry, hehe : P – horseyguy