Using Fixnum, Strings etc. in Modules


#1

I’m stuck on why this occurs. (using jRuby 1.1.5 & Ruby 1.8.6)

I’m trying to use modules to scope certain class overrides, so say the
String class is changed in ModuleA i don’t want it to affect ModuleB.
But when i try to accomplish this i run in to two things.

First, when creating a Module and overwriting, just for example, the
reverse method. results in an error:
module ModuleA
class String; def reverse;false;end; end
p String.new(“abc”).reverse
end

Okay, so it creates its own class String instead of taking the core
class String. Basicly what i want is the module to have it’s own set of
core classes.

Secondly, when using direct instantiation in a module it wont use the
overwritten class, example:
module ModuleA
class String < String; def reverse;false;end; end
p String.new(“abc”).reverse
p “abc”.reverse
end

Results in:
false
cba
Instead of false; false

Could anyone point me in the right drection, thanks in advanced !


#2

On Wed, Mar 18, 2009 at 6:10 AM, Bram W. removed_email_address@domain.invalid
wrote:

 p String.new(“abc”).reverse
p String.new(“abc”).reverse
p “abc”.reverse
end

Results in:
false
cba
Instead of false; false

Could anyone point me in the right drection, thanks in advanced !

I don’t think its possible to do exactly what you are trying to do
without fundamentally altering the core of Ruby: you can’t, as far as
I know, alter a class only for purposes of calls from a particular
module, and literals will always use the top level class (::String,
etc.) not ::String. As your code above shows, you can
just avoid using literals and always use explicit constructor calls in
your module to use the local version.


#3

2009/3/18 Christopher D. removed_email_address@domain.invalid:

class String; def reverse;false;end; end
class String < String; def reverse;false;end; end

I don’t think its possible to do exactly what you are trying to do
without fundamentally altering the core of Ruby: you can’t, as far as
I know, alter a class only for purposes of calls from a particular
module, and literals will always use the top level class (::String,
etc.) not ::String. As your code above shows, you can
just avoid using literals and always use explicit constructor calls in
your module to use the local version.

Absolutely agree! Fiddling with core classes is a bad idea™.

And you cannot alter the return type of String constructors “” and ‘’.

Another solution is to use a functional approach

module A
def self.reverse(str)
false
end
end

You could as well use delegation to wrap core classes with other
classes and add / change functionality. That’s probably the most OO
approach. Changing core classes brings all sorts of problems and I
strongly suggest to not do it.

Cheers

robert