Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > using Enumerable when each has arguments?

Reply
Thread Tools

using Enumerable when each has arguments?

 
 
Erwin Abbott
Guest
Posts: n/a
 
      05-21-2007
Hi

I've written a number of classes which would benefit from the
Enumerable mixin, but my #each method requires arguments. These are
usually to specify the range of values, like Fibonacci#each(first,
last) or whatever. Since Enumerable's #map, #collect, etc don't take
arguments, how should I proceed? I would be okay with wrapping the
Enumerable methods I need, but that doesn't seem possible. Do I just
have to implement my own #map, #to_a, etc?

Thanks,
Erwin

 
Reply With Quote
 
 
 
 
Robert Klemme
Guest
Posts: n/a
 
      05-21-2007
On 21.05.2007 12:41, Erwin Abbott wrote:
> I've written a number of classes which would benefit from the
> Enumerable mixin, but my #each method requires arguments. These are
> usually to specify the range of values, like Fibonacci#each(first,
> last) or whatever. Since Enumerable's #map, #collect, etc don't take
> arguments, how should I proceed? I would be okay with wrapping the
> Enumerable methods I need, but that doesn't seem possible. Do I just
> have to implement my own #map, #to_a, etc?


Just use Enumerator:

12:54:27 [client_1]: irb -r enumerator
irb(main):001:0> class Foo
irb(main):002:1> include Enumerable
irb(main):003:1> def each(a,b,&bl) (a..b).each(&bl); self end
irb(main):004:1> end
=> nil
irb(main):005:0> Foo.new.each(1,5) {|x| p x}
1
2
3
4
5
=> #<Foo:0x7ef7e9b8>
irb(main):006:0> Foo.new.to_enum(:each,1,5).map {|x| x+x}
=> [2, 4, 6, 8, 10]

Btw, is your Foibonacci#each really an instance method or rather a class
method? If it is an instance method you might as well store arguments
in the instance, so you do

Fibonacci.new(1,10).each {|fib| puts fib}

Kind regards

robert
 
Reply With Quote
 
 
 
 
Trans
Guest
Posts: n/a
 
      05-21-2007


On May 21, 6:41 am, "Erwin Abbott" <erwin.abb...@gmail.com> wrote:
> Hi
>
> I've written a number of classes which would benefit from the
> Enumerable mixin, but my #each method requires arguments. These are
> usually to specify the range of values, like Fibonacci#each(first,
> last) or whatever. Since Enumerable's #map, #collect, etc don't take
> arguments, how should I proceed? I would be okay with wrapping the
> Enumerable methods I need, but that doesn't seem possible. Do I just
> have to implement my own #map, #to_a, etc?


The standard response is "use enumerator and to_enum". but if you feel
like me, that's equivalent to tying knots in your spaghetti noodles to
save money on rotini.

I heard rumor that a future Ruby will ultimately pass thru each
parameters, but in the mean time you can have a go with Facets
enumerablepass.rb (http://facets.rubyforge.org).

An alternative is to use a functor (a function delegator) for your
parameters, eg.

f = Foo.new
f.range(1,5).each{|x| p x}

T.


 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      05-21-2007
On 21.05.2007 15:27, Trans wrote:
>
> On May 21, 6:41 am, "Erwin Abbott" <erwin.abb...@gmail.com> wrote:
>> Hi
>>
>> I've written a number of classes which would benefit from the
>> Enumerable mixin, but my #each method requires arguments. These are
>> usually to specify the range of values, like Fibonacci#each(first,
>> last) or whatever. Since Enumerable's #map, #collect, etc don't take
>> arguments, how should I proceed? I would be okay with wrapping the
>> Enumerable methods I need, but that doesn't seem possible. Do I just
>> have to implement my own #map, #to_a, etc?

>
> The standard response is "use enumerator and to_enum". but if you feel
> like me, that's equivalent to tying knots in your spaghetti noodles to
> save money on rotini.


I on the other hand am a big fan of Enumerator.

> I heard rumor that a future Ruby will ultimately pass thru each
> parameters, but in the mean time you can have a go with Facets
> enumerablepass.rb (http://facets.rubyforge.org).


That's a good solution.

> An alternative is to use a functor (a function delegator) for your
> parameters, eg.
>
> f = Foo.new
> f.range(1,5).each{|x| p x}


.... which is basically the same as using to_enum - only less portable;
to_enum works with *all* methods.

Kind regards

robert
 
Reply With Quote
 
Trans
Guest
Posts: n/a
 
      05-21-2007


On May 21, 10:35 am, Robert Klemme <shortcut...@googlemail.com> wrote:

> > An alternative is to use a functor (a function delegator) for your
> > parameters, eg.

>
> > f = Foo.new
> > f.range(1,5).each{|x| p x}

>
> ... which is basically the same as using to_enum - only less portable;
> to_enum works with *all* methods.


That true. But at least it reads much better.

T.


 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      05-21-2007
On 21.05.2007 17:51, Trans wrote:
>
> On May 21, 10:35 am, Robert Klemme <shortcut...@googlemail.com> wrote:
>
>>> An alternative is to use a functor (a function delegator) for your
>>> parameters, eg.
>>> f = Foo.new
>>> f.range(1,5).each{|x| p x}

>> ... which is basically the same as using to_enum - only less portable;
>> to_enum works with *all* methods.

>
> That true. But at least it reads much better.


Even that is subjective: I personally prefer to read f.to_enum(:range,
1, 5) because then I know this is going to be capable of all the
Enumerable methods. YMMD though.

Kind regards

robert
 
Reply With Quote
 
James Edward Gray II
Guest
Posts: n/a
 
      05-21-2007
On May 21, 2007, at 10:55 AM, Robert Klemme wrote:

> On 21.05.2007 17:51, Trans wrote:
>> On May 21, 10:35 am, Robert Klemme <shortcut...@googlemail.com>
>> wrote:
>>>> An alternative is to use a functor (a function delegator) for your
>>>> parameters, eg.
>>>> f = Foo.new
>>>> f.range(1,5).each{|x| p x}
>>> ... which is basically the same as using to_enum - only less
>>> portable;
>>> to_enum works with *all* methods.

>> That true. But at least it reads much better.

>
> Even that is subjective: I personally prefer to read f.to_enum
> (:range, 1, 5) because then I know this is going to be capable of
> all the Enumerable methods. YMMD though.


I agree. It's also worth noting that to_enum() is aliased to enum_for
() which I think often reads a little better.

James Edward Gray II

 
Reply With Quote
 
Erwin Abbott
Guest
Posts: n/a
 
      05-21-2007
Thanks for the replies. I hadn't looked at Enumerator before, I think
that will do the trick. I kind of agree it's not the prettiest looking
code, but I'll write my own #map, #to_a, etc and won't have to look at
it again.

> I heard rumor that a future Ruby will ultimately pass thru each
> parameters, but in the mean time you can have a go with Facets
> enumerablepass.rb (http://facets.rubyforge.org).


I'll look into that too... I see quite a lot of people using facets in
the code and have been meaning to check it out. It seems like passing
parameters along would've been easy and very useful, I'm sort of
surprised it's not already that way.

Cheers,
Erwin

On 5/21/07, James Edward Gray II <> wrote:
> On May 21, 2007, at 10:55 AM, Robert Klemme wrote:
>
> > On 21.05.2007 17:51, Trans wrote:
> >> On May 21, 10:35 am, Robert Klemme <shortcut...@googlemail.com>
> >> wrote:
> >>>> An alternative is to use a functor (a function delegator) for your
> >>>> parameters, eg.
> >>>> f = Foo.new
> >>>> f.range(1,5).each{|x| p x}
> >>> ... which is basically the same as using to_enum - only less
> >>> portable;
> >>> to_enum works with *all* methods.
> >> That true. But at least it reads much better.

> >
> > Even that is subjective: I personally prefer to read f.to_enum
> > (:range, 1, 5) because then I know this is going to be capable of
> > all the Enumerable methods. YMMD though.

>
> I agree. It's also worth noting that to_enum() is aliased to enum_for
> () which I think often reads a little better.
>
> James Edward Gray II
>
>


 
Reply With Quote
 
Rick DeNatale
Guest
Posts: n/a
 
      05-21-2007
On 5/21/07, Trans <> wrote:


> I heard rumor that a future Ruby will ultimately pass thru each
> parameters,


I'm not sure that that means in general, but what the current 1.9 does
is to first make Enumerator part of the standard library, and to make
each and other similar methods return an enumerator for the method and
it's parameters in cases where no block is given.

i.e. (in ruby 1.9)

e = "abc".each_byte
is equivalent to
e = "abc".enum_for(:each_byte)

and
e = array.each_slice(2)
is equivalent to
e = array.enum_for(:each_slice, 2)

and you can do things like:

"abc".each_byte.inject {|sum, chr| sum + chr}


--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

 
Reply With Quote
 
James Edward Gray II
Guest
Posts: n/a
 
      05-21-2007
On May 21, 2007, at 12:46 PM, Rick DeNatale wrote:

> On 5/21/07, Trans <> wrote:
>
>
>> I heard rumor that a future Ruby will ultimately pass thru each
>> parameters,

>
> I'm not sure that that means in general, but what the current 1.9 does
> is to first make Enumerator part of the standard library...


Enumerator is part of the standard library (libraries shipped with
Ruby) in Ruby 1.8. 1.9 mores the library to the core (no require
needed).

James Edward Gray II



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Transform a 2D color image into 2 images of (R1,G1,B) at each pixelof image 1 and (R2,G2,B) at each pixel of image2 for STEREO visualization 88888 Dihedral C++ 10 12-23-2011 02:28 PM
Array#each - getting each element and the index Pat Maddox Ruby 6 01-20-2006 04:04 PM
Enumerable methods returning Enumerable (was: ruby-dev suumary 26862-26956) Daniel Sheppard Ruby 0 09-16-2005 02:40 AM
how do i? Full scan of each control in each grid row cell John Blair ASP .Net 1 08-03-2005 11:02 AM
xsl:for-each for each 3 elements problem Tjerk Wolterink XML 3 11-03-2004 05:22 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57