JSON.parseとJSON.loadの違い
JSON.parseとJSON.loadの差が何なのか分からなかったので調べてみた。
※下記の参考のStackOverflowの内容がその答えだが、裏を取りたかった。
require 'json' File.open("hoge.json") do |f| JSON.parse(f.read) == File.open("hoge.json"){ |f| JSON.load(f) } ? p("same") : p("diffrent") end => "same"
※File.openを2回呼んでいるのはどげんかせんといかん。
Rubyの公式ドキュメント:parse、:loadを見ると、parseはparamのsourceがJSONの文字列しか受け付けないのに対して、 loadはto_str,to_io, readを持つオブジェクトもparamのsourceに指定可能と記載されている。
githubのJSON.loadの実装を見ると、loadがparseをラップしているのが分かる。
今回のようにファイルから読み込む場合、parseはreadから返された文字列が、loadはFile.to_io.readで返された文字列が使われる為、両方供同じようにfileからJSONファイルを読み込める形になるようだ。
loadはドキュメントの通り、loadに渡されたオブジェクトがto_str,to_io,readのどれかを返せばいいので、 String以外のオブジェクトからparseを呼び出す際は、loadを使用する形になるのではないかと思う。
参考
StackOverflow:What’s the difference between JSON.load and JSON.parse methods of Ruby lib?
classとそれが読み込んでいるmoduleの一覧を表示する方法
クラスの継承関係と各クラスで読み込んでいるモジュールの一覧を表示したかったので作ってみた。
def display_class_modules(class_name) print "class:#{class_name},modules:#{class_name.included_modules}","\n" if class_name.respond_to?(:included_modules) display_class_modules(class_name.superclass) if class_name.respond_to?(:superclass) end display_class_modules(1.class) #=> class:Fixnum,modules:[Comparable, Kernel] #=> class:Integer,modules:[Comparable, Kernel] #=> class:Numeric,modules:[Comparable, Kernel] #=> class:Object,modules:[Kernel] #=> class:BasicObject,modules:[]
1のクラスはFixnumでComparableとKernelモジュールをインクルードしている事と、 継承チェーンがFixnum->Integer->Numeric->Object->BasicObjectの順に上がっている事が分かる。
疑問点
- Moduleは何処に行ったのだろう?(included_modulesにclass_nameが反応しているのにModule自体がイングルードしているモジュール一覧に出てこない)
改善ポイント
- moduleの中のinclude関係も見れるとよい
- もっと簡潔に書きたい(respond_to?とかまとめて書けないか)