[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Are we cool? method_missing in enumerator

Trans

7/17/2007 2:01:00 PM

Can anyone demonstrate problems with the following?

# Adds immediate elementwise ability to Enumerator.
# Any non-enumeration method is passed on to each.
#
# [1,2,3].to_enum(:map) + 3
# => [4,5,6]
#
# Note there may be a few essential methods this can not
# be used on, such as #object_id.

class Enumerable::Enumerator
def method_missing(sym,*args,&blk)
each{ |x| x.send(sym,*args,&blk) }
end
end

I like the simplicity of this and would rather use it than add an
another class layer, but I need to be sure I'm not overlooking any
potential dangers with doing so.

Thanks,
T.


14 Answers

Robert Klemme

7/17/2007 2:13:00 PM

0

2007/7/17, Trans <transfire@gmail.com>:
> Can anyone demonstrate problems with the following?
>
> # Adds immediate elementwise ability to Enumerator.
> # Any non-enumeration method is passed on to each.
> #
> # [1,2,3].to_enum(:map) + 3
> # => [4,5,6]
> #
> # Note there may be a few essential methods this can not
> # be used on, such as #object_id.
>
> class Enumerable::Enumerator
> def method_missing(sym,*args,&blk)
> each{ |x| x.send(sym,*args,&blk) }
> end
> end
>
> I like the simplicity of this and would rather use it than add an
> another class layer, but I need to be sure I'm not overlooking any
> potential dangers with doing so.

Cool indeed! The only thing that comes to mind at the moment is a
certain inconsistency that this creates: all methods implemented in
the Enumerator are methods operating on the collection while methods
invoked by your extension are invoked per instance in the collection.
I am not sure whether that actually disqualifies the change as a std
lib change...

Btw, your sample would be equally simple by doing [1,2,3].map {|x|
x+3} - it's even less typing. ;-)

Kind regards

robert

Robert Dober

7/17/2007 2:21:00 PM

0

On 7/17/07, Trans <transfire@gmail.com> wrote:
> Can anyone demonstrate problems with the following?
>
> # Adds immediate elementwise ability to Enumerator.
> # Any non-enumeration method is passed on to each.
> #
> # [1,2,3].to_enum(:map) + 3
> # => [4,5,6]
> #
> # Note there may be a few essential methods this can not
> # be used on, such as #object_id.
>
> class Enumerable::Enumerator
> def method_missing(sym,*args,&blk)
> each{ |x| x.send(sym,*args,&blk) }
> end
> end
>
> I like the simplicity of this and would rather use it than add an
> another class layer, but I need to be sure I'm not overlooking any
> potential dangers with doing so.
>
Hmm I do it like this in Labrador, but on map directly and I add a
class overlay so that indeed things like #object_id can be dispatched

irb(main):002:0> require 'labrador/enum'
=> true
irb(main):003:0> [1,2,3].map.object_id
=> [3, 5, 7]
irb(main):004:0>

I would indeed be very interested in dangers of this, but my
announcement went unnoticed, quite normal given the undocumented and
unstructured state of Labrador -- I work less than 1h/w for it :(.

I really do not like -- or know -- this to_enum stuff, it seems way to
verbose for me.
Attention I am not going to influence the community I just want to
find some fellow soul who likes my style. (Notably Magic Dot)

Sorry if I am hijacking a little bit, just say a word and I'll go away...

Robert
--
I always knew that one day Smalltalk would replace Java.
I just didn't know it would be called Ruby
-- Kent Beck

Robert Dober

7/17/2007 2:23:00 PM

0

On 7/17/07, Robert Klemme <shortcutter@googlemail.com> wrote:

>
> Btw, your sample would be equally simple by doing [1,2,3].map {|x|
> x+3} - it's even less typing. ;-)
I offer
irb(main):001:0> require 'labrador/enum'
=> true
irb(main):002:0> (1..3).map + 3
=> [4, 5, 6]
irb(main):003:0> (1..3).map(:+, 3)
=> [4, 5, 6]
>
> Kind regards
>
> robert
>
>
Robert


--
I always knew that one day Smalltalk would replace Java.
I just didn't know it would be called Ruby
-- Kent Beck

Sammy Larbi

7/18/2007 3:01:00 PM

0

I might test that it can still throw missing method exception if the
called method isn't supposed to be doing what you're making it do (ie,
perhaps it was a typo)

Sam


Trans wrote, On 7/17/2007 9:01 AM:
> Can anyone demonstrate problems with the following?
>
> # Adds immediate elementwise ability to Enumerator.
> # Any non-enumeration method is passed on to each.
> #
> # [1,2,3].to_enum(:map) + 3
> # => [4,5,6]
> #
> # Note there may be a few essential methods this can not
> # be used on, such as #object_id.
>
> class Enumerable::Enumerator
> def method_missing(sym,*args,&blk)
> each{ |x| x.send(sym,*args,&blk) }
> end
> end
>
> I like the simplicity of this and would rather use it than add an
> another class layer, but I need to be sure I'm not overlooking any
> potential dangers with doing so.
>
> Thanks,
> T.
>
>
>
>
>


Trans

7/18/2007 4:12:00 PM

0



On Jul 17, 7:22 am, "Robert Dober" <robert.do...@gmail.com> wrote:
> On 7/17/07, Robert Klemme <shortcut...@googlemail.com> wrote:
>
>
>
> > Btw, your sample would be equally simple by doing [1,2,3].map {|x|
> > x+3} - it's even less typing. ;-)
>
> I offer
> irb(main):001:0> require 'labrador/enum'
> => true
> irb(main):002:0> (1..3).map + 3
> => [4, 5, 6]
> irb(main):003:0> (1..3).map(:+, 3)
> => [4, 5, 6]

Yep. This works with my implementation too as of Ruby 1.9+ because the
enumerable methods will return an enumerator if no block is given.

T.


Trans

7/18/2007 4:17:00 PM

0



On Jul 18, 8:01 am, Sammy Larbi <s...@powersource.com> wrote:
> I might test that it can still throw missing method exception if the
> called method isn't supposed to be doing what you're making it do (ie,
> perhaps it was a typo)
>
> Sam
>
> Trans wrote, On 7/17/2007 9:01 AM:
>
> > Can anyone demonstrate problems with the following?
>
> > # Adds immediate elementwise ability to Enumerator.
> > # Any non-enumeration method is passed on to each.
> > #
> > # [1,2,3].to_enum(:map) + 3
> > # => [4,5,6]
> > #
> > # Note there may be a few essential methods this can not
> > # be used on, such as #object_id.
>
> > class Enumerable::Enumerator
> > def method_missing(sym,*args,&blk)
> > each{ |x| x.send(sym,*args,&blk) }
> > end
> > end
>
> > I like the simplicity of this and would rather use it than add an
> > another class layer, but I need to be sure I'm not overlooking any
> > potential dangers with doing so.

Yea, that's the "danger" part, because it's going to try to apply that
typo to the enumerable's elements. I many cases that will no doubt
fail --in which case maybe it wouldn't hurt to but it in a begin
rescue clause in order to give a more comprehensible error message.
OTOH, some typos might get through, in which case testing is key.

I think I've come up with a good alternative that is safer, but still
reads well (as of 1.9):

arr.map.x + 3

What do you think?

T.


Robert Dober

7/18/2007 8:49:00 PM

0

On 7/18/07, Trans <transfire@gmail.com> wrote:
>
>
> On Jul 18, 8:01 am, Sammy Larbi <s...@powersource.com> wrote:
> > I might test that it can still throw missing method exception if the
> > called method isn't supposed to be doing what you're making it do (ie,
> > perhaps it was a typo)
This being true, where exactly is the difference between

enum.map{ |e| e.typo }
and
enum.map(:typo)

<snip>
Robert

--
I always knew that one day Smalltalk would replace Java.
I just didn't know it would be called Ruby
-- Kent Beck

Daniel DeLorme

7/18/2007 11:02:00 PM

0

Trans wrote:
> I think I've come up with a good alternative that is safer, but still
> reads well (as of 1.9):
>
> arr.map.x + 3
>
> What do you think?

I'll throw out this idea from a thread not so long ago:

arr.map.it + 3

;)
Daniel

Trans

7/19/2007 2:51:00 AM

0



On Jul 18, 1:48 pm, "Robert Dober" <robert.do...@gmail.com> wrote:
> On 7/18/07, Trans <transf...@gmail.com> wrote:
>
> > On Jul 18, 8:01 am, Sammy Larbi <s...@powersource.com> wrote:
> > > I might test that it can still throw missing method exception if the
> > > called method isn't supposed to be doing what you're making it do (ie,
> > > perhaps it was a typo)
>
> This being true, where exactly is the difference between
>
> enum.map{ |e| e.typo }
> and
> enum.map(:typo)

Hmm... that's very good point!

T.


dblack

7/19/2007 6:45:00 AM

0