Extending class, namespace question

Hi everybody,

I have this:

class Fixnum
def times_print(str)
times { puts str }
end
end

module Bb
def self.test
10.times_print(‘foo’)
end
test
end

It works…

But if some other .rb uses the same name for its Fixnum class extension,
including different methods, there will be collision ??

So I tried to wrap my class extension in a module like this:

module Aa
class Fixnum
def times_print(str)
times { puts str }
end
end
end

module Bb
include Aa
def self.test

10.times_print('foo')

end
test
end

The class-extention in module Bb does not work, how do I solve this>??

Thnx!!

On Thu, Aug 16, 2012 at 2:16 PM, Ronnie Aa [email protected] wrote:

end

module Aa
include Aa
def self.test

10.times_print('foo')

end
test
end

The class-extention in module Bb does not work, how do I solve this>??

When you say

module Aa
class Fixnum

This is not the same Fixnum as the top-level Fixnum. This is
Aa::Fixnum, of which 10 is not an instance. You can refer to a
top-level constant prefixing it with “::”. So:

module Aa
class ::Fixnum

Jesus.

Hi,

A Ruby integer is always an instance of the built-in classes ::Fixnum or
::Bignum. You cannot have different integers depending on the
surrounding module.

This is actually a good thing, because you certainly don’t want such
elementary objects to behave context-dependend. Imagine you make a
calculation and get different results for different modules.

I would generally avoid messing with the built-in classes. Sometimes it
does make sense to add convenience methods, but something like
“print_times” isn’t really worth it in my opinion.

Thanx for your answers!

So its better to not extend built-in classes, and ::Fixnum
has nothing todo with Module::Fixnum , in the latter it’s just
a custom name for some class?

Rene

On Thu, Aug 16, 2012 at 2:16 PM, Ronnie Aa [email protected] wrote:

10.times_print('foo')

end
test
end

It works…

But if some other .rb uses the same name for its Fixnum class extension,
including different methods, there will be collision ??

Yes. And with that you have exactly nailed one of the major reasons
why your change is not a good idea. :slight_smile: There are actually more
reasons, e.g. that a number has no job in containing printing methods.

So I tried to wrap my class extension in a module like this:

module Aa
class Fixnum
def times_print(str)
times { puts str }
end
end
end

Here you create a new class ::Aa::Fixnum which is totally unrelated to
::Fixnum…

module Bb
include Aa
def self.test

10.times_print('foo')

end
test
end

The class-extention in module Bb does not work, how do I solve this>??

… which you now discovered. :slight_smile:

Just do

10.times { print ‘foo’ }

Kind regards

robert

Jan E. wrote in post #1072596:

Ronnie Aa wrote in post #1072589:

So its better to not extend built-in classes, and ::Fixnum
has nothing todo with Module::Fixnum , in the latter it’s just
a custom name for some class?

Yes, yes and yes. :wink:

But what about:

http://rubyworks.github.com/rubyfaux/?doc=http://rubyworks.github.com/facets/docs/facets-2.9.3/core.json#api-class-Array

These guys could make a living extending built-in classes. :slight_smile:

On 17/08/2012, at 11:26 PM, Ronnie Aa wrote:

http://rubyworks.github.com/rubyfaux/?doc=http://rubyworks.github.com/facets/docs/facets-2.9.3/core.json#api-class-Array

These guys could make a living extending built-in classes. :slight_smile:

As with everything in life, it’s fine to extend built in classes as long
as you’re aware of the potential problems.

Henry

Ronnie Aa wrote in post #1072589:

So its better to not extend built-in classes, and ::Fixnum
has nothing todo with Module::Fixnum , in the latter it’s just
a custom name for some class?

Yes, yes and yes. :wink:

Jan E. wrote in post #1072542:

A Ruby integer is always an instance of the built-in classes ::Fixnum or
::Bignum. You cannot have different integers depending on the
surrounding module.

This is actually a good thing, because you certainly don’t want such
elementary objects to behave context-dependend.

I think that’s exactly what the proposed ruby 2.0 “refinements” are
intended to do.