Are we cool? method_missing in enumerator

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.

2007/7/17, Trans [email protected]:

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. :wink:

Kind regards

robert

On 7/17/07, Robert K. [email protected] wrote:

Btw, your sample would be equally simple by doing [1,2,3].map {|x|
x+3} - it’s even less typing. :wink:
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 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

On 7/17/07, Trans [email protected] wrote:

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

On Jul 18, 8:01 am, Sammy L. [email protected] wrote:

Adds immediate elementwise ability to Enumerator.

  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.

On Jul 17, 7:22 am, “Robert D.” [email protected] wrote:

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 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

:wink:
Daniel

On 7/18/07, Trans [email protected] wrote:

On Jul 18, 8:01 am, Sammy L. [email protected] 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)

Robert

Hi –

On Thu, 19 Jul 2007, 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’m afraid there’s too much “invisible ink” there for me.

David

2007/7/19, [email protected] [email protected]:

I’m afraid there’s too much “invisible ink” there for me.

That’s a great way to put it! With your (other) own words, I think
this is unbalanced. Too much coolness, to few readability.

Kind regards

robert

On Jul 18, 1:48 pm, “Robert D.” [email protected] wrote:

and
enum.map(:typo)

Hmm… that’s very good point!

T.

On Jul 19, 2:45 am, [email protected] wrote:

I’m afraid there’s too much “invisible ink” there for me.
Well, what does that mean? Clearly you find it uncomfortable in some
manner. Is it just the magic-dot again? Or something else? Is the
original

arr.map + 3

okay? Or are both too much “invisible ink”. What is wrong with it/them
more concretely?

Thanks,
T.

Robert D. wrote, On 7/18/2007 3:48 PM:

and
enum.map(:typo)

Robert

Good point. I guess I was thinking of something unrelated to the map
call: Where you’ve got the magic behavior working fine, but somewhere
later on you have a method typo, but that gets caught by method_missing
and throws some different strange error instead of method missing.

Sam

On 7/19/07, Tanner B. [email protected] wrote:

arr.map + 3
new_arr = arr.map + 3

without knowing a lot of specifics about arr, map, and this magic, I would
totally assume that map is an attribute of arr, and you’re adding 3 to it.

This sort of shortcut is the kind of thing I would use in a DSL where
certain context is assumed, but wouldn’t use in day to day programming, it’s
just too ambiguous.
This is indeed true, the art might be to find the balance (how is it
going David? :wink: between conciseness and readability.
Your DSL example is excellent because it restricts users to a circle
talking the same jargon, more generally I think one has to think about
who will read the code.
Consistency comes in too ( I did not do it on purpose ) if you write
all your code like that a potential new team member or maintainer will
learn your ways quickly…

Robert

On 7/19/07, Trans [email protected] wrote:

arr.map.x + 3

okay? Or are both too much “invisible ink”. What is wrong with it/them
more concretely?

At a glance, I can’t tell if arr is a object with an attribute named map
that you’re adding 3 to (and never storing). Does this return a value,
or
does it modify in place? If it returns a value, then you’d end up with a
statement like

new_arr = arr.map + 3

without knowing a lot of specifics about arr, map, and this magic, I
would
totally assume that map is an attribute of arr, and you’re adding 3 to
it.

This sort of shortcut is the kind of thing I would use in a DSL where
certain context is assumed, but wouldn’t use in day to day programming,
it’s
just too ambiguous.

Thanks,