Forum: Ruby Why none of the block giving the expected output with the "enumerator"?

Posted by Love U Ruby (my-ruby)
on 2013-02-02 21:20
Why none of the block giving the expected output with the "enumerator"?

=======================================================================
irb(main):017:0> a=[11,22,31,224,44].to_enum
=> #<Enumerator: [11, 22, 31, 224, 44]:each>
irb(main):018:0> a.each{|x| x%2 == 0}
=> [11, 22, 31, 224, 44]
irb(main):019:0> a.each{|x| x%4 == 0}
=> [11, 22, 31, 224, 44]
irb(main):020:0> a.each{|x| x > 22 }
=> [11, 22, 31, 224, 44]
irb(main):021:0> a.each{|x,y| x-y }
TypeError: nil can't be coerced into Fixnum
        from (irb):21:in `-'
        from (irb):21:in `block in irb_binding'
        from (irb):21:in `each'
        from (irb):21:in `each'
        from (irb):21
        from C:/Ruby193/bin/irb:12:in `<main>'
irb(main):022:0> a.each{|x,y| (x-y) }
TypeError: nil can't be coerced into Fixnum
        from (irb):22:in `-'
        from (irb):22:in `block in irb_binding'
        from (irb):22:in `each'
        from (irb):22:in `each'
        from (irb):22
        from C:/Ruby193/bin/irb:12:in `<main>'
irb(main):023:0>
======================================================================
Posted by Stefano Crocco (crocco)
on 2013-02-02 21:34
(Received via mailing list)
On Sunday 03 February 2013 Arup Rakshit wrote
> => [11, 22, 31, 224, 44]
>         from (irb):22:in `-'
>         from (irb):22:in `block in irb_binding'
>         from (irb):22:in `each'
>         from (irb):22:in `each'
>         from (irb):22
>         from C:/Ruby193/bin/irb:12:in `<main>'
> irb(main):023:0>
> ======================================================================
>
> --
> Posted via http://www.ruby-forum.com/.

You create an enumerator from an array. When the enumerator's each 
method is
called, it'll call the array's each method, which calls the block for 
every
element and returns the array itself.

In your first example, you execute the expression x%2==0 for each 
element, but
you do nothing for the result. If you want to display the result, you'll 
need
something like

a.each{|x| puts(x%2==0)}

If you want to select only those elements you'll want to use 
Enumerable#select
rather than Enumerable#each:

a1 = a.select{|x| x%2==0}

I hope this helps

Stefano
Posted by Love U Ruby (my-ruby)
on 2013-02-02 21:44
Stefano Crocco wrote in post #1094918:
> On Sunday 03 February 2013 Arup Rakshit wrote
>> => [11, 22, 31, 224, 44]
>>         from (irb):22:in `-'
>>         from (irb):22:in `block in irb_binding'
>>         from (irb):22:in `each'
>>         from (irb):22:in `each'
>>         from (irb):22
>>         from C:/Ruby193/bin/irb:12:in `<main>'
>> irb(main):023:0>

@Stefano why is it calling Array's "each" method,instead of 
"enum#each",as i converted it to enumerator?

thanks
Posted by Stefano Crocco (crocco)
on 2013-02-02 22:00
(Received via mailing list)
On Sunday 03 February 2013 Arup Rakshit wrote
> >>         from C:/Ruby193/bin/irb:12:in `<main>'
> >>
> >> irb(main):023:0>
>
> @Stefano why is it calling Array's "each" method,instead of
> "enum#each",as i converted it to enumerator?
>
> thanks
>
> --
> Posted via http://www.ruby-forum.com/.

Because Enumerator#each, in turn, calls the each method of the object it 
was
created from.

It is (more or less) if the enumerator was created this way:

class Enumerator

  def initialize object, method = :each
    @object = object
    @method = method
    @args = args
  end

  def each
    @object.send :method, *args
  end

end

Actually, Enumerator is written in C, so its implementation is different 
from
this.

So, when you create an enumerator from an array, the #each method of the
Enumerator calls the #each method of the array.

Stefano
Posted by Love U Ruby (my-ruby)
on 2013-02-02 22:07
Stefano Crocco wrote in post #1094920:
> On Sunday 03 February 2013 Arup Rakshit wrote

@Stefano ->

Could you simulate the same example with the enum#each method, just to 
understand the difference between enum#each and array#each?


Thanks
Posted by Stefano Crocco (crocco)
on 2013-02-02 22:24
(Received via mailing list)
On Sunday 03 February 2013 Arup Rakshit wrote
>
> --
> Posted via http://www.ruby-forum.com/.

Again, there's no difference, since Enumerator#each (when the Enumerator 
was
created from an array) calls Array.each.

To clarify things, imagine we create a new class, MyArray, which 
contains an
array (to make things simple, we pass the array to the constructor). 
This
class has an #each method which takes a block (using the &blk syntax), 
then
displays the text "Calling MyArray#each", then calls the #each method of 
the
internal array:


class MyArray

  def initialize a
    @array = a
  end

  def each &blk
    puts "Calling MyArray#each"
    @array.each &blk
  end

end

Now, we create an instance of MyArray, and create an enumerator from it.

ma = MyArray.new [1,2,3,4,5]
e = ma.to_enum

Now, try calling the each method once on ma and once on e, and you'll 
see that
they produce the same output:

ma.each{|i| puts i}
e.each{|i| puts i}

In both cases, the output is:

Calling MyArray#each
1
2
3
4
5
=> [1, 2, 3, 4, 5]

As you can see, there's no difference between the two calls.

Stefano
Posted by Love U Ruby (my-ruby)
on 2013-02-02 22:34
Stefano Crocco wrote in post #1094924:
> On Sunday 03 February 2013 Arup Rakshit wrote
>>

@Stefano

Perfect explanation and I understood. What I meant is that to give an 
example which will call and work as enum#each.

Thanks
Posted by unknown (Guest)
on 2013-02-02 22:54
(Received via mailing list)
Am 02.02.2013 21:20, schrieb Arup Rakshit:
> Why none of the block giving the expected output with the "enumerator"?

They do, you have wrong expectations. (You really should read the docs
and google for examples/tutorials/... to build the right expectations.)

(BTW, next time please *tell us* what your expected output would have
  been.)

> =======================================================================
> irb(main):017:0> a=[11,22,31,224,44].to_enum
> => #<Enumerator: [11, 22, 31, 224, 44]:each>
> irb(main):018:0> a.each{|x| x%2 == 0}
> => [11, 22, 31, 224, 44]
> irb(main):019:0> a.each{|x| x%4 == 0}
> => [11, 22, 31, 224, 44]
> irb(main):020:0> a.each{|x| x > 22 }
> => [11, 22, 31, 224, 44]

First, you do not need to_enum here, simply use Array#each.

Second, the blocks behave exactly as should be expected.

What you probably meant was something like

   1.9.3-p194 :001 > a = [11, 22, 31, 224, 44]
    => [11, 22, 31, 224, 44]
   1.9.3-p194 :002 > a.each {|item| puts item  if item % 2 == 0 }
   22
   224
   44
    => [11, 22, 31, 224, 44]

You did not 'do' anything with the logical expression inside the block.

What you probably misinterpreted as the output (the part after '=>')
is actually the value of the evaluated expresssion, which in this case
is the return value of the each method (-> the array itself, see docs).
Besides the output generated by puts statements etc., irb always
additionally outputs the value of the evaluated expression.

> irb(main):021:0> a.each{|x,y| x-y }
> TypeError: nil can't be coerced into Fixnum
>          from (irb):21:in `-'
>          from (irb):21:in `block in irb_binding'
>          from (irb):21:in `each'
>          from (irb):21:in `each'
>          from (irb):21
>          from C:/Ruby193/bin/irb:12:in `<main>'

This cannot work, because #each yields exactly one parameter (see docs).
y therefore always is nil and nil cannot be subtracted from x.
Posted by Love U Ruby (my-ruby)
on 2013-02-02 23:12
unknown wrote in post #1094928:
> Am 02.02.2013 21:20, schrieb Arup Rakshit:

> What you probably misinterpreted as the output (the part after '=>')
> is actually the value of the evaluated expresssion, which in this case
> is the return value of the each method (-> the array itself, see docs).
> Besides the output generated by puts statements etc., irb always
> additionally outputs the value of the evaluated expression.
>
>> irb(main):021:0> a.each{|x,y| x-y }
>> TypeError: nil can't be coerced into Fixnum
>>          from (irb):21:in `-'
>>          from (irb):21:in `block in irb_binding'
>>          from (irb):21:in `each'
>>          from (irb):21:in `each'
>>          from (irb):21
>>          from C:/Ruby193/bin/irb:12:in `<main>'
>
> This cannot work, because #each yields exactly one parameter (see docs).
> y therefore always is nil and nil cannot be subtracted from x.

`+1` to you. You guided me perfectly! :)
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.