From: Joel VanderWerf Date: 2004-03-15T06:19:41+09:00 Subject: yaml and ruby symbols Since today is apparently the first day of the new YAML year, or at least a major event on the YAML calendar, here's something else I've been wondering about. I tend to prefer symbols to strings as hash keys (for immutability and efficiency reasons), but I'm not crazy about how they look in YAML: irb> y({:foo=>1}) --- !ruby/sym foo: 1 whereas string keys look more natural: irb> y({"foo"=>1}) --- foo: 1 Yet it seems that YAML.load is quite capable of recognizing a nice, natural format for symbols: irb> s="---\n:foo: 1\n" irb> puts s --- :foo: 1 irb> YAML.load(s) => {:foo=>1} And this notation is not ambiguous with strings that happen to begin with a colon: irb> y({":foo"=>1}) --- ":foo": 1 Is it possible for Symbol#to_yaml to take an option that will dump symbols in this simpler way? (You'd lose some portability, I guess, so maybe the option should not be on by default.) This is the implementation I tried, but apparently I don't understand how the opts argument of #to_yaml gets propagated (or why it doesn't). require 'yaml' class Symbol def to_yaml( opts = {} ) YAML::quick_emit( nil, opts ) { |out| out << (opts[:simple_symbols] ? ":" : "!ruby/sym ") self.id2name.to_yaml( :Emitter => out ) } end end foo_yaml = :foo.to_yaml({:simple_symbols => true}) puts foo_yaml # ==> # --- :foo # # Good so far! foo = YAML.load(foo_yaml) p foo # ==> # :foo # # Still good. h = {:foo=>1} puts h.to_yaml # ==> # --- # !ruby/sym foo: 1 # # Expected. puts h.to_yaml({:simple_symbols => true}) # ==> # --- # !ruby/sym foo: 1 # # Expected: # --- # :foo: 1