# Extending a core class cleanly \[noobish alert\]

**URL:** <https://www.ruby-forum.com/t/extending-a-core-class-cleanly-noobish-alert/191118>\
**Category:** Ruby\
**Created:** [July 5, 2010, 10:30pm UTC](https://www.ruby-forum.com/t/extending-a-core-class-cleanly-noobish-alert/191118 "2010-07-05T22:30:41Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![fearless\_fool](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/5e9695/32.png) [@fearless\_fool](https://www.ruby-forum.com/u/fearless_fool)\
**Post date:** [July 5, 2010, 10:30pm UTC](https://www.ruby-forum.com/t/extending-a-core-class-cleanly-noobish-alert/191118/1 "2010-07-05T22:30:41Z")

</div>

Assume I’d like to create a statistics package designed to work on  
Arrays [but see P.S.]. One way to do this would be to create functions  
that take an array as an argument:

def mean(array)  
return NaN unless array && array.size \> 0  
array.reduce(0.0) {|accum, val| accum + val} / array.size  
end

… but that’s so old school. What I’d really like is to _cleanly_  
extend the Array class so you can operate on it directly, as in:

> > [1, 2, 3].mean  
> > =\> 2.0

I’m sure that it’s considered bad style to simply open the Array class  
and extend it, since that can lead to unexpected user surprises:

class Array  
def mean  
return NaN unless self.size \> 0  
self.reduce(0.0) {|accum, val| accum + val} / self.size  
end  
end

My hunch is that the stats functions should be wrapped in a module and  
then included (extended?) when desired. But despite reading the  
tutorials and docs, I’m not sure what’s considered the stylistically  
correct way (and the syntax) to package that up.

Comments? Pointers?

Thanks!

- ff

[P.S.: Before you tell me about available stats packages, etc, note that  
I’m only using statistics as an example. My real question is about  
extending a class…]

---

<div class="post-metadata">

**Author:** ![fearless\_fool](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/5e9695/32.png) [@fearless\_fool](https://www.ruby-forum.com/u/fearless_fool)\
**Post date:** [July 5, 2010, 11:22pm UTC](https://www.ruby-forum.com/t/extending-a-core-class-cleanly-noobish-alert/191118/2 "2010-07-05T23:22:57Z")

</div>

On Monday, July 05, 2010 03:30:44 pm Fearless F. wrote:

> ```
> return NaN unless self.size > 0
> self.reduce(0.0) {|accum, val| accum + val} / self.size
> end
> 
> ```
> 
> end

What kind of surprises?

> My hunch is that the stats functions should be wrapped in a module and  
> then included (extended?) when desired. But despite reading the  
> tutorials and docs, I’m not sure what’s considered the stylistically  
> correct way (and the syntax) to package that up.

Simple enough:

module MyModule  
def mean  
…  
end  
end

Then, you can always do this:

[].extend MyModule

Or this:

class Array  
include MyModule  
end

Then, probably, provide a file people can ‘require’ that’ll do the  
inclusion  
for them, maybe even make that the default.

It might also be nice to provide a way to do this on Enumerables, though  
that  
would be less efficient if you know you have an array. For example:

def mean  
size = 0  
count = inject(0){|accum, val| size+=1; accum+val}  
count / size.to\_f  
end

---

<div class="post-metadata">

**Author:** ![fearless\_fool](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/5e9695/32.png) [@fearless\_fool](https://www.ruby-forum.com/u/fearless_fool)\
**Post date:** [July 6, 2010, 1:16am UTC](https://www.ruby-forum.com/t/extending-a-core-class-cleanly-noobish-alert/191118/3 "2010-07-06T01:16:07Z")

</div>

David M. wrote:

> What kind of surprises?

Coming from conventional programming environments, one might be  
surprised when a core class suddenly acquires new methods – e.g.  
Rails/ActiveSupport’s extensions to String – so I wanted to make sure I  
was packaging such extensions properly.

> Simple enough:  
> [snip]

Perfect – I see how that works now. Thank you.

> Then, probably, provide a file people can ‘require’ that’ll do the  
> inclusion for them, maybe even make that the default.

… or if I was feeling adventuresome, perhaps an autoload?

> It might also be nice to provide a way to do this on Enumerables, though  
> that would be less efficient if you know you have an array.

Good catch. If I _do_ implement a stats package, I’ll think about  
making it ambidextrous.

Thanks again.

- ff

---

<div class="post-metadata">

**Author:** ![fearless\_fool](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/5e9695/32.png) [@fearless\_fool](https://www.ruby-forum.com/u/fearless_fool)\
**Post date:** [July 6, 2010, 9:31am UTC](https://www.ruby-forum.com/t/extending-a-core-class-cleanly-noobish-alert/191118/4 "2010-07-06T09:31:45Z")

</div>

On Mon, Jul 5, 2010 at 11:22 PM, David M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> > … but that’s so old school. What I’d really like is to _cleanly_  
> > def mean  
> > correct way (and the syntax) to package that up.
> 
> [].extend MyModule

I agree, this is the less dangerous thing to do: just extend the  
specific array instances with your functionality. That way, all other  
arrays are left intact.

Jesus.

---

<div class="post-metadata">

**Author:** ![fearless\_fool](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/5e9695/32.png) [@fearless\_fool](https://www.ruby-forum.com/u/fearless_fool)\
**Post date:** [July 7, 2010, 2:59am UTC](https://www.ruby-forum.com/t/extending-a-core-class-cleanly-noobish-alert/191118/5 "2010-07-07T02:59:48Z")

</div>

On Monday, July 05, 2010 06:16:10 pm Fearless F. wrote:

> David M. wrote:
> 
> > What kind of surprises?
> 
> Coming from conventional programming environments, one might be  
> surprised when a core class suddenly acquires new methods – e.g.  
> Rails/ActiveSupport’s extensions to String – so I wanted to make sure I  
> was packaging such extensions properly.

Libraries like that do tend to isolate the syntactic sugar from the  
utility  
code. I think the idea is that you might do this instead:

module MathStuff  
def mean(array)  
…  
end  
end

And then, in another file:

class Array  
def mean  
MathStuff.mean self  
end  
end

This might be overkill, but the idea here is: If you just require  
activesupport, you get all the extensions to string. If you require  
active\_support/inflector, you get all the string manipulation methods,  
without  
ever having to extend a string – all your strings stay pure.

I actually don’t see a problem with extending String, and I don’t see  
what the  
conventional argument is. The _only_ potential problem is namespace  
conflicts  
– if two different libraries define String#pluralize, and it means a  
different thing to each library, you’ve got a problem.

> > Then, probably, provide a file people can ‘require’ that’ll do the  
> > inclusion for them, maybe even make that the default.
> 
> … or if I was feeling adventuresome, perhaps an autoload?

That only automatically works if you then extend/include it at some  
point. So,  
for example, it might make sense like this:

autoload :MathStuff, ‘whatever’  
…  
[].extend MathStuff

It would be kind of wasteful here:

autoload :MathStuff, ‘whatever’  
class Array

# always loads right now

include MathStuff  
end

And it’d be completely useless otherwise.
