2011-12-20 1 views
4

개체에 to_hash을 해킹하고있었습니다 (이 것은 좋은 생각 인 것만은 아닙니다). 이상한 문제를 발견했을 때 IO이 작동을 멈췄습니다.원숭이 패치 개체가 이상한 결과를냅니다.

run_test1에서
#lib/object.rb 
class Object 
    def to_hash 
    self.instance_variables.inject({}) { |hash,var| hash[var.to_s.delete("@")] = self.instance_variable_get(var); hash } 
    end 
end 

#run_test1.rb 
require_relative 'lib/Object' 
require 'FileUtils' 

puts 'run test' 


#run_test2.rb 
require_relative 'lib/Object' 

File.open('test.txt', 'w') {|f| f.write('this is a test')} 

내가

run_test2.rb:3:in `initialize': No such file or directory - test.txt (Errno::ENOENT 
     from run_test2.rb:3:in `open' 
     from run_test2.rb:3:in `<main>' 

을 얻을 run_test2에

<internal:lib/rubygems/custom_require>:29:in `set_encoding': wrong number of arguments (0 for 1..2) (ArgumentError) 
     from <internal:lib/rubygems/custom_require>:29:in `require' 
     from <internal:lib/rubygems/custom_require>:29:in `require' 
     from .../run_test1.rb:2:in `<main>' 

을 얻을

동안 (파일이 존재하는 경우 파일이 쓰기를 위해 열려 있지 말한다) 나는 그것이 일어났다는 것에 놀라지 않는다. 단지 궁금해서, 여기서 무엇이 일어나고 있는가? 이론적으로는 근본적인 원인은 무엇이든지 괜찮을 것입니다.

관련 정보 :

  • 루비 1.9.2p290 (2011-07-09) [I386-mingw32]
  • XP SP3 32 비트
  • 젬 버전 : 1.8.12
+4

저급 개체를 변경하면 의도하지 않은 결과가 발생할 수 있다고 생각한 사람은 누구입니까? * 왜 * 이런 식으로 물건을 부수는지 알기 위해서 (''pry''에서 훨씬 더 흥미 롭습니다.)'to_hash'가 물건을 깨뜨리는 이유를 알아 내기 위해 C를 추적해야 할 수도 있습니다. , 이미 거기에 있기 때문에 그렇지 않습니다. 누가 알아. 'to_hashish'는 잘 작동하기 때문에 명확하게 심볼과 관련이 있습니다. –

+2

닫기/아래로 투표하는 이유는 무엇입니까? 왜 놀랍습니까? 조금 놀랍다 고해도 * 왜 * 이것이 뭔가를 어기는지 알고 싶을 때 유용합니다 (특히 그것이하는 방식으로). –

+0

덕분에 나는 내 길을 계속 가다듬어 다른 일을 깨뜨릴 것이다. 재미있어 보인다. – jtzero

답변

2

to_hash 메서드는 해시를 강요하는 객체를 식별하는 데 사용됩니다. 그러한 의미에서, 그것은 to_ary 또는 to_str처럼 동작합니다. 구현 한 방법은 to_a 또는 to_s입니다.

Ruby 코어 코드를 비롯한 많은 Ruby 코드는 인수가 옵션 해시 (arg.respond_to? :to_hash)인지 여부와 그 실행 경로가 다른 실행 경로를 따르는지를 확인하기 위해 to_hash을 확인합니다. 객체가 실제 해시인지 여부에 따라 코드 검사를 통해 더 많은 것을 망칠 수 있습니다 (Hash === arg).

to_h 또는 이와 비슷한 이름을 지정할 수도 있습니다.