Forum: Ruby Using Fixnum, Strings etc. in Modules

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
E52519d40b12374080235e62dcf615f9?d=identicon&s=25 Bram Wijnands (bram__)
on 2009-03-18 14:13
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 !
D7463bd611f227cfb2ef4da4a978a203?d=identicon&s=25 Christopher Dicely (Guest)
on 2009-03-18 15:54
(Received via mailing list)
On Wed, Mar 18, 2009 at 6:10 AM, Bram Wijnands <brambomail@gmail.com>
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 <CurrentModule>::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.
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2009-03-18 16:32
(Received via mailing list)
2009/3/18 Christopher Dicely <cmdicely@gmail.com>:
>> 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 <CurrentModule>::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(TM).

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
This topic is locked and can not be replied to.