2011-12-20 13 views
4

私はObjectにto_hashをハッキングしていました(これは良いアイデアだとは言えません。私が奇妙な問題に出くわしたとき、IOは働きませんでした。 run_test1でmonkey patchingオブジェクトが奇妙な結果を生成する

#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で

<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>' 

を取得し、私は

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>' 

を取得する(ファイルが存在する場合には、ファイルが書き込み用にオープンされていないと言う)

ながら私はそれが起こったことに驚くことではない - ただ好奇心が強い、ここで何が起こっているの?理論的にはうまくいくはずですが、根本原因は何か。

関連情報:

  • ルビー1.9.2p290(2011-07-09)[I386-MINGW32]
  • XP SP3 32ビット
  • RubyGemsのバージョン: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などの名前を付けたい場合があります。