2012-01-22 3 views
11

저는 Ruby에서 메타 프로그래밍을 배우고 있으며 method_missing과 define_method를 통해 누락 된 메소드를 정의하려고합니다. 나는 예상치 못한 행동을하고있어 누군가가 이것을 설명 할 수 있는지 궁금해하고 있습니다. 여기 내 클래스 : 이제루비 : 왜 to_ary에 전화를 걸까요?

class X 
    def method_missing(m, *args, &block) 
    puts "method #{m} not found. Defining it." 
    self.class.send :define_method, m do 
     puts "hi from method #{m}" 
    end 
    puts "defined method #{m}" 
    end 
end 

,이 코드는 왜 루비가 호출 : 나는하지 않는 무엇

method some_method not found. Defining it. 
defined method some_method 

hi from method some_method 

method to_ary not found. Defining it. 
defined method to_ary 
#<X:0x007fcbc38e5030> 

마지막 부분입니다 :

x = X.new 

x.some_method 
puts 
x.some_method 
puts 
puts x 

출력을 생성합니다 to_ary에 전화를 걸어? 왜 Ruby는 내 객체를 배열로 변환하려고합니까?

나는 주위를 봤와 한

발견이 관련 링크 :

이 또한 method_missing 및 to_ary 개는 이야기가 아니라 구체적으로 둔다는 to_ary 부를 것이다 이유에 대해 .

to_s를 정의 할 때 동작이 변경되지 않는다는 점도 언급해야합니다.

def to_s 
    "I'm an instance of X" 
end 

"풋의 X"의 출력

다음이다 :

method to_ary not found. Defining it. 
defined method to_ary 
I'm an instance of X 

답변

14

puts$stdout.puts는 동의어이다. $ 표준 출력이 IO 클래스, 그래서 IO.puts에 대한 설명서를 보면 :

는 IO 번호 인쇄와 마찬가지로 IOS에, 지정된 오브젝트를 기입합니다. 개행 문자 (대개 개행 문자)를 새 문자 시퀀스 으로 끝나지 않은 채로 기록합니다. 배열 인수를 사용하여 호출하면 각 행에 새 요소를 씁니다.

즉, puts 메서드는 여러 줄의 출력을 작성합니다. 따라서 객체의 to_ary 메소드를 호출하려고 시도하고 to_ary이 정의 된 경우 반환 된 Array의 각 요소를 새 줄에 인쇄합니다. 그렇지 않으면 putsto_s 메소드를 호출합니다.

to_ary 내부 사용은 정말 잘 (그의 루비 프로그래밍 언어 책에서 마츠 지점이를) 루비 문서에 문서화되어 있지 않습니다.

방법 반면 printpto_ary을 호출하지 말고 to_s 만 호출하십시오.

(!) 참고 : 재미, to_ary 실제 Array 객체가 아닌 each 방법 또는 다른 것을 정의하는 개체를 반환해야합니다 :

class Test 
    def to_ary 
    10.downto(1) 
    end 
end 

puts Test.new 

#TypeError: can't convert Test to Array (Test#to_ary gives Enumerator) 
#  from (irb):28:in `puts' 
#  from (irb):28:in `puts' 
#  from (irb):28 
+0

감사합니다. 나는 본질이 "to_ary 내부 사용법은 Ruby 문서에 잘 설명되어 있지 않습니다"라고 생각합니다. :) IO.puts 워드 프로세서를 읽었을 때, 명시 적으로 to_ary를 언급하지 않았을 때, 이것이 더 분명해질 것이라고 생각합니다. "루비 프로그래밍 언어"책을 가리켜 주셔서 감사합니다. –

관련 문제