I am embedding multiple Ruby interpreters in a single Java program
(using the newer preferred embedding mechanism “Red Bridge”, although
I doubt that matters for this problem). I am using a single Java
HashMap to communicate state between the different interpreters, I’ll
call this the GlobalVariableStorage. Don’t ask why I’m doing all this
– I am probably using JRuby in ways that was never intended, but I am
sure I want to be doing it
Anyway, here’s the situation. Interpreter1 puts a nil object in the
GlobalVariableStorage, then interpreter2 pulls the nil object out of
there and compares it to nil like this:
nil_from_global_storage == nil
And this always returns false! Both are instances of NilClass. The
workaround is to do something like:
nil_from_global_store.nil?
But the problem goes deeper than that. Symbol equality fails too. So
if I put :some_symbol in the GlobalVariableStorage, and pull it out in
a different interpreter and do this:
some_symbol_from_global_storage == :some_symbol
That will always be false too. The workaround I came up with in this
case is to convert everything to a String (I guess because it calls
Java’s String.equal() method?).
I think I understand why this is happening. My theory is that Ruby
assumes there is only one instance of NilClass (because it typically
is a singleton) and one instance of every distinct symbol. So for
efficiency it probably just does an object equality check when you
call the == method. This seems perfectly reasonable, so I can’t even
really claim that the behavior I described is a bug.
But I’m curious what the JRuby developers think about this situation?
Write it off as an unsupported use case and I’ll stick to my
workarounds? Or do you think that two different instances of NilClass
should always be considered equal and this could be improved? What
about the situation with symbols?
I hope my description is clear enough. I can put together some example
code if needed.
Adam