clouder
12/11/2007 8:09:00 PM
I had some time wrapping my head around this one messing with irb
I was wondering why b.compact! would change the value of a
As i continually tried doing
a =3D [1,2,3]
b =3D a
b =3D [1,3,4]
and was getting a =3D> [1,2,3] and b =3D> [1,3,4]
After trying with strings and gsub and such it finally dinged that b=3Da
has assigned 'b' to the object stored in 'a', so running a method on
it was effecting the object stored in both 'a' and 'b'. Where as when
I was doing b =3D [1,3,4] it was creating a new object all together so
'a' was never effected. Is this correct? If so, sorry for making a
dumb post if everyone else git this :X I thought I'd post it anyways
to possibly help some poor soul like me struggling over why this might
not work as expected.
On Dec 11, 7:45 am, Phrogz <phr...@mac.com> wrote:
> On Dec 11, 2:28 am, Stefano Crocco <stefano.cro...@alice.it> wrote:
>
>
>
> > Alle marted=EC 11 dicembre 2007, lianliming ha scritto:
>
> > > Hi all,
>
> > > Is there any build-in method of class Array which can be used to find
> > > the first non-nil element in an array? I can't find any so I am trying=
> > > to achieve it by my own approach. I don't think my approach is smart
> > > enough, so I would like to know better one to do so. Here is what I am=
> > > doing:
>
> > > a =3D [nil, "hello", "world"]
> > > b =3D a
> > > b.compact!
> > > first_non_nil_elem =3D b.first
>
> > > I don't call "compact!" directly on a because it will change a's
> > > structure, I want to reserve nil elements in a.
>
> > > Any suggestions are really appreciated!
>
> > You can use Enumerable#find, which will return the first item in the arr=
ay for
> > which the block returns true:
>
> > a =3D [nil, "hello", "world"]
> > puts a.find{|i| !i.nil?}
> > =3D> "hello"
>
> > By the way, you can use compact, instead of compact! to avoid using the
> > temporary variable b:
>
> > a =3D [nil, "hello", "world"]
> > first_non_nil_elem =3D a.compact.first
>
> > While compact! removes the nil elements from the receiver, compact retur=
ns a
> > new array with the nil element removed.
>
> Moreover, there was no reason to assign to the 'b' variable in the
> first place. Doing so doesn't duplicate the array, but just creates
> another reference to it. The compact! method still modified the same
> array:
>
> irb(main):006:0> a =3D [ nil, "foo", "bar" ]
> =3D> [nil, "foo", "bar"]
>
> irb(main):007:0> b =3D a
> =3D> [nil, "foo", "bar"]
>
> irb(main):008:0> b.compact!
> =3D> ["foo", "bar"]
>
> irb(main):009:0> a
> =3D> ["foo", "bar"]
>
> So if the intent was, as I assume, to preserve the original array with
> the nil values, that's even more reason to use #compact instead of
> #compact!