From: Brandon Weaver Date: 2012-09-20T14:10:34+09:00 Subject: Re: the behavior of iterator methods --047d7b33d8d6895d5a04ca1b24a9 Content-Type: text/plain; charset=ISO-8859-1 On Wed, Sep 19, 2012 at 10:43 PM, Jam Bees wrote: > Some methods change objects in place, others return a changed object and > leave the original in place. > > The bang is placed by convention at the end of methods that have some > unusual behavior; most often, this unusual behavior is that a data > structure is passed in by reference not by value. > > On Sep 19, 2012, at 9:32 PM, ten ten wrote: > > > Hi all, > > > > Sorry, I deleted my previous post on the ruby forum by mistake. > > So I post it again. > > > > > > > > I am a Ruby-beginner. > > I have some experience of C/C++ for several years. > > It has been only one week since I started to learn Ruby. > > Please tell me about the behavior of iterator methods. > > > > At first, I did as bellow on the irb environment. > > ------------------------------------------------------- > > irb(main):001:0> s = ["a", "b", "c"] > > => ["a", "b", "c"] > > irb(main):002:0> s[0].object_id > > => 36971304 > > irb(main):003:0> s[1].object_id > > => 36971292 > > irb(main):004:0> s[2].object_id > > => 36971280 > > irb(main):005:0> s.each{|c| c.upcase!} > > => ["A", "B", "C"] > > irb(main):006:0> p s > > ["A", "B", "C"] > > => nil > > ------------------------------------------------------- > > > > Looking at this, I thought I can change the value of each element in > > Array object through iterator methods. > > > > However, when I did next as bellow, that behavior looked different. > > ------------------------------------------------------- > > irb(main):007:0> a = [1,2,3] > > => [1, 2, 3] > > irb(main):008:0> a[0].object_id > > => 3 > > irb(main):009:0> a[1].object_id > > => 5 > > irb(main):010:0> a[2].object_id > > => 7 > > irb(main):011:0> a.each{|i| i += 1} > > => [1, 2, 3] > > irb(main):012:0> p a > > [1, 2, 3] > > => nil > > > > irb(main):013:0> a.each{|i| p i.object_id} > > 3 > > 5 > > 7 > > => [1, 2, 3] > > ------------------------------------------------------- > > > > I expected that Array#each method with the code block would change > > contents of the Array object variable named 'a' into [2,3,4]. > > But it didn't. Why? > > > > The object IDs of a[0], a[1], a[2] are shown through > > the the code block of Array#each. So I thought if variable named 'i' > > changed its value, that had to be reflected to the Array object 'a'. > > But it didn't. > > > > > > Why did this difference happened? > > > > -- > > Posted via http://www.ruby-forum.com/. > > > > You may also want to look into the map method for similar functionality. String arrays are more easily constructed using %w (for single quote) and %W (for double quote) like so: a = %w(a b c) b = a.map!{ |word| word.upcase } puts b # Returns: # A # B # C http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-map This is what you're probably looking for. Make sure to read that page as well as the one on enumerators, quite a bit of sugar and goodies to be had to those who read deep into those docs. Depending on your paradigm/style though, some would say that bang methods should not be used to preserve the purity of a variable. To be fair, that's a functional mindset of stateless variables and immutability, and seeing how you come from a C type background I doubt you code that way. Ruby is a hybrid that allows you to engage in some functional behavior, but a good bit of it is encouraged by the style, such as Blocks. I would look into Blocks, Procs, and Lambdas. The bit in the {} (or can also be do end) is what's called a block. Procs and Lambdas are basically storing Blocks for reuse. The |i| is the iterator variable. Make sure to pay close attention to yields, injects, and other such methods in both Blocks and Enumerables, it'll save you a load of time. (For instance: (1..5).inject(:*) will return 120, or 5! (factorial)) http://www.robertsosinski.com/2008/12/21/understanding-ruby-blocks-procs-and-lambdas/ This should get you well on your way in that regard. Feel free to ask if you're having any more trouble, always glad to help. Brandon Weaver --047d7b33d8d6895d5a04ca1b24a9 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
On Wed, Sep 19, 2012 at 10:43 PM, Jam Bees <= span dir=3D"ltr"><jam@jamandbees.net> wrote:

On Sep 19, 2012, at 9:32 PM, ten ten <lists@ruby-forum.com> wrote:

> Hi all,
>
> Sorry, I deleted my previous post on the ruby forum by mistake.
> So I post it again.
>
>
>
> I am a Ruby-beginner.
> I have some experience of C/C++ for several years.
> It has been only one week since I started to learn Ruby.
> Please tell me about the behavior of iterator methods.
>
> At first, I did as bellow on the irb environment.
> -------------------------------------------------------
> irb(main):001:0> s =3D ["a", "b", "c"= ]
> =3D> ["a", "b", "c"]
> irb(main):002:0> s[0].object_id
> =3D> 36971304
> irb(main):003:0> s[1].object_id
> =3D> 36971292
> irb(main):004:0> s[2].object_id
> =3D> 36971280
> irb(main):005:0> s.each{|c| c.upcase!}
> =3D> ["A", "B", "C"]
> irb(main):006:0> p s
> ["A", "B", "C"]
> =3D> nil
> -------------------------------------------------------
>
> Looking at this, I thought I can change the value of each element in > Array object through iterator methods.
>
> However, when I did next as bellow, that behavior looked different. > -------------------------------------------------------
> irb(main):007:0> a =3D [1,2,3]
> =3D> [1, 2, 3]
> irb(main):008:0> a[0].object_id
> =3D> 3
> irb(main):009:0> a[1].object_id
> =3D> 5
> irb(main):010:0> a[2].object_id
> =3D> 7
> irb(main):011:0> a.each{|i| i +=3D 1}
> =3D> [1, 2, 3]
> irb(main):012:0> p a
> [1, 2, 3]
> =3D> nil
>
> irb(main):013:0> a.each{|i| p i.object_id}
> 3
> 5
> 7
> =3D> [1, 2, 3]
> -------------------------------------------------------
>
> I expected that Array#each method with the code block would change
> contents of the Array object variable named 'a' into [2,3,4].<= br> > But it didn't. Why?
>
> The object IDs of a[0], a[1], a[2] are shown through
> the the code block of Array#each. So I thought if variable named '= i'
> changed its value, that had to be reflected to the Array object 'a= '.
> But it didn't.
>
>
> Why did this difference happened?
>
> --
> Posted via ht= tp://www.ruby-forum.com/.
>



You may also want to= look into the map method for similar functionality.

String arrays are more easily constructed using %w (for single quote) an= d %W (for double quote) like so:

a =3D %w(a b c)
b =3D a.map!{ |word| word.upcase }
puts b

# Returns:
# A
# B
# C


This is what you're probably looking for. Make sure= to read that page as well as the one on enumerators, quite a bit of sugar = and goodies to be had to those who read deep into those docs.

Depending on your paradigm/style though, some would say that= bang methods should not be used to preserve the purity of a variable. To b= e fair, that's a functional mindset of stateless variables and immutabi= lity, and seeing how you come from a C type background I doubt you code tha= t way. Ruby is a hybrid that allows you to engage in some functional behavi= or, but a good bit of it is encouraged by the style, such as Blocks.

I would look into Blocks, Procs, and Lambdas. The bit i= n the {} (or can also be do end) is what's called a block. Procs and La= mbdas are basically storing Blocks for reuse. The |i| is the iterator varia= ble. Make sure to pay close attention to yields, injects, and other such me= thods in both Blocks and Enumerables, it'll save you a load of time.

(For instance: (1..5).inject(:*) will return 120, or 5!= (factorial))


This should get you well on your way in that regard.

Feel free to ask if you're having any more troub= le, always glad to help.

Brandon Weaver
--047d7b33d8d6895d5a04ca1b24a9--