Basically I have two modules: CoreExtensions::CamelcasedJsonString
and …::CamelcasedJsonSymbol
. The latter one overrides the Symbol#to_s
, so that the method returns a String
which is extended with the first module. I don't want every string to be a CamelcasedJsonString
. This is the reason why I try to apply the extension instance specific.
My problem is, that Symbol#to_s
seems to be overridden again after I included my module (the last spec fails):
require 'rubygems' if RUBY_VERSION < '1.9'
require 'spec'
module CoreExtensions
module CamelcasedJsonString; end
module CamelcasedJsonSymbol
alias to_s_before_core_extension to_s
def to_s(*args)
to_s_before_core_extension(*args).extend(CamelcasedJsonString)
end
end
::Symbol.send :include, CamelcasedJsonSymbol
end
describe Symbol do
subject { :chunky_bacon }
it "should be a CamelcasedJsonSymbol" do
subject.should be_a(CoreExtensions::CamelcasedJsonSymbol)
end
it "should respond to #to_s_before_core_extension" do
subject.should respond_to(:to_s_before_core_extension)
end
specify "#to_s should return a CamelcasedJsonString" do
subject.to_s.should be_a(CoreExtensions::CamelcasedJsonString)
end
end
However the following example works:
require 'rubygems' if RUBY_VERSION < '1.9'
require 'spec'
module CoreExtensions
module CamelcasedJsonString; end
end
class Symbol
alias to_s_before_core_extension to_s
def to_s(*args)
to_s_before_core_extension(*args).extend(CoreExtensions::CamelcasedJsonString)
end
end
describe Symbol do
subject { :chunky_bacon }
it "should respond to #to_s_before_core_extension" do
subject.should respond_to(:to_s_before_core_extension)
end
specify "#to_s should return a CamelcasedJsonString" do
subject.to_s.should be_a(CoreExtensions::CamelcasedJsonString)
end
end
Update: Jan 24, 2010
The background of my problem is that I try to convert a huge nested hash
structure into a JSON string. Each key in this hash is a Ruby Symbol
in the
typical underscore notation. The JavaScript library which consumes the JSON
data expects the keys to be strings in camelcase notation. I thought that
overriding the Symbol#to_json
method might be the easiest way. But that
didn't work out since Hash#to_json
calls first #to_s
and afterwards
#to_json
on each key. Therefore I thought it might be a solution to extend
all Strings returnd by Symbol#to_s
with a module which overrides the
#to_json
method of this specific string instance to return a string that has
a #to_json
method which returns itself in camelcase notation.
I'm not sure if there is an easy way to monkey patch Hash#to_json
.
If someone wants to take a look into the JSON implementation I'm using, here is the link: http://github.com/flori/json/blob/master/lib/json/pure/generator.rb (lines 239 and following are of interest)