Newbie doesn't understand why's example

in why's poignant guide to ruby…
class ArrayMine < Array
  # Build a string from this array, formatting each entry
  # then joining them together.
  def join( sep = $, format = "%s" )
    collect do |item|
     sprintf( format, item )
    end.join( sep )<<<<big confusing stmt
  end
end
why doesn't this loop recursively forever? what's happening here at the
big confusing stmt??? please explain…tia

···

--
Posted via http://www.ruby-forum.com/.

    collect do |item|
     sprintf( format, item )
    end.join( sep )<<<<big confusing stmt

#collect return an Array : this mean that ruby will call Array#join rather
than ArrayMine#join

moulon% ruby -e 'class A < Array; end; a = A[1, 2]; p a.class; p a.collect {|i| i}.class'
A
Array
moulon%

Guy Decoux

dave rose <bitdoger2@yahoo.com> writes:

in why's poignant guide to ruby...
class ArrayMine < Array
  # Build a string from this array, formatting each entry
  # then joining them together.
  def join( sep = $, format = "%s" )
    collect do |item|
     sprintf( format, item )
    end.join( sep )<<<<big confusing stmt
  end
end
why doesn't this loop recursively forever? what's happening here at the
big confusing stmt??? please explain....tia

collect returns an Array, as has been said.
Maybe it is clearer if you use a Variable:
foo= collect do |item|
     sprintf( format, item )
end

foo.join(sep)

I am probably "old school," but when learning new things -- seeing is
understanding, try this:

class ArrayMine < Array
  # Build a string from this array, formatting each entry
  # then joining them together.
  def join( sep = $, format = "%s" )
    puts "I am in #{self.class}#join"
    x = collect do |item|
     sprintf( format, item )
    end
    puts "Calling #{x.class}#join "
    x.join( sep )
  end
end

Keep trying it is worth it
pth

....your one-liner below is even more confusing for this newbie...i
already know what collect & sprintf does...i'm just hung-up on that
'end.join' part...why doesn't endlessly recursively call itself....i
guess to remove all doubt in a clearer multi-line example show the wrong
way that will endlessly recursively call itself so that i can know in
better detail.what's happening...??? tia...

ts wrote:

···

> collect do |item|
> sprintf( format, item )
> end.join( sep )<<<<big confusing stmt

#collect return an Array : this mean that ruby will call Array#join
rather
than ArrayMine#join

moulon% ruby -e 'class A < Array; end; a = A[1, 2]; p a.class; p
a.collect {|i| i}.class'
A
Array
moulon%

Guy Decoux

--
Posted via http://www.ruby-forum.com/\.

thanx patrick...i guess i'm 'old school'....dave
Patrick Hurley wrote:

···

I am probably "old school," but when learning new things -- seeing is
understanding, try this:

    puts "Calling #{x.class}#join "
    x.join( sep )
  end
end

Keep trying it is worth it
pth

--
Posted via http://www.ruby-forum.com/\.

collect do |item|
   sprintf( format, item )
end.join( sep )<<<<big confusing stmt

Well write it like this

   x = collect do |item|
      sprintf( format, item )
   end
   x.join(sep)

First store the result of #collect in `x', then call x.join

`x' is an Array, ruby just call Array#join and not ArrayMine#join

Guy Decoux

Read Guy's post again. It's all there. The two occurrences of .join call
completely different functions. His one-liner just provides proof of what he
has written above it.

Marc Migge

all of you, have all been some help here...but i'm still confused and
i'm not trying split hairs here but what's in the syntax of
end.join(sep) or foo=foo.join(sep) that ruby doesn't recursively recall
arraymine's join.... another words based on previous why's (or other
tutorials that i've seen)
def fact(n)
if n=1 return 1
else
  return n*fact(n-1)<<<<what's the difference in the syntax from
'end.join(sep)'
end
end
it's still recalling the function's name....
Please give an example where the arraymine (or any other example) join
WOULD recursively recall itself so that i can see the difference....
another words how differently is Arraymine inherenting the Array join
method and/or extending it and at what point does ruby know the
difference??? just by the syntax alone???
Marc Dominik Migge wrote:

···

Read Guy's post again. It's all there. The two occurrences of .join call
completely different functions. His one-liner just provides proof of
what he
has written above it.

Marc Migge

--
Posted via http://www.ruby-forum.com/\.

Please give an example where the arraymine (or any other example) join
WOULD recursively recall itself so that i can see the difference....

Well, here a recursive function

moulon% cat b.rb
#!/usr/bin/ruby
class ArrayMine < Array
   # Build a string from this array, formatting each entry
   # then joining them together.
   def join( sep = $, format = "%s" )
      x = collect {|item| sprintf( format, item ) }
      y = ArrayMine.new(x)
      y.join(sep)
   end
end

p ArrayMine[1,2].join
moulon%

First it create an Array `x'
Create an object ArrayMine `y'
Then call #join for `y' (i.e. ArrayMine#join)

moulon% ./b.rb
./b.rb:6:in `join': stack level too deep (SystemStackError)
  from ./b.rb:8:in `join'
  from ./b.rb:12
moulon%

The original version is

moulon% cat b.rb
#!/usr/bin/ruby
class ArrayMine < Array
   # Build a string from this array, formatting each entry
   # then joining them together.
   def join( sep = $, format = "%s" )
      x = collect {|item| sprintf( format, item ) }
      x.join(sep)
   end
end

p ArrayMine[1,2].join
moulon%

First it create an Array `x'
Then call #join for `x' (i.e. Array#join)

moulon% ./b.rb
"12"
moulon%

Guy Decoux

Helge's example would recursivly call itself.

As mentioned before .collect returns an object of class Array. So calling

  collect do |item|
  ...
  end.join(sep) # "end" ends the do block

is essentially the same as

  collect { |item| ... }.join(sep)

In each case collect evaluates to

  [item1, item2, ...] # an Array object of items

So the result is the same as if you had

  [item1, item2, ...].join(sep) # calls Array#join not ArrayMain#join

There is nothing special in the Ruby syntax here. In Java you could do the
same thing, e.g.

  funtionThatReturnsAnArray().length()

The main difference between the two languages in this matter is that in Ruby
you can call methods on what Java people might call "primitives type
constants", e.g.

  5.times {puts "hello"}

Maybe the "blocks" (the stuff between "{" and "}" or, alternativley "do" and
"end") confused you here.

Marc Migge

···

On 6/27/06, dave rose <bitdoger2@yahoo.com> wrote:

all of you, have all been some help here...but i'm still confused and
i'm not trying split hairs here but what's in the syntax of
end.join(sep) or foo=foo.join(sep) that ruby doesn't recursively recall
arraymine's join.... another words based on previous why's (or other
tutorials that i've seen)
def fact(n)
if n=1 return 1
else
  return n*fact(n-1)<<<<what's the difference in the syntax from
'end.join(sep)'
end
it's still recalling the function's name....
Please give an example where the arraymine (or any other example) join
WOULD recursively recall itself so that i can see the difference....
another words how differently is Arraymine inherenting the Array join
method and/or extending it and at what point does ruby know the
difference??? just by the syntax alone???
Marc Dominik Migge wrote:
> Read Guy's post again. It's all there. The two occurrences of .join call
> completely different functions. His one-liner just provides proof of
> what he
> has written above it.
>
> Marc Migge

--
Posted via http://www.ruby-forum.com/\.

The stumbling block here seems to be that x is an instance of class Array,
and not your new class, ArrayMine. To make it infinitely recursive, x would
have to be of type ArrayMine. To do this you would have to override the
collect method to return an ArrayMine instead of an Array.

···

On 6/27/06, ts <decoux@moulon.inra.fr> wrote:

> Please give an example where the arraymine (or any other example) join
> WOULD recursively recall itself so that i can see the difference....

Well, here a recursive function

moulon% cat b.rb
#!/usr/bin/ruby
class ArrayMine < Array
   # Build a string from this array, formatting each entry
   # then joining them together.
   def join( sep = $, format = "%s" )
      x = collect {|item| sprintf( format, item ) }
      y = ArrayMine.new(x)
      y.join(sep)
   end
end

p ArrayMine[1,2].join
moulon%

First it create an Array `x'
Create an object ArrayMine `y'
Then call #join for `y' (i.e. ArrayMine#join)

moulon% ./b.rb
./b.rb:6:in `join': stack level too deep (SystemStackError)
        from ./b.rb:8:in `join'
        from ./b.rb:12
moulon%

The original version is

moulon% cat b.rb
#!/usr/bin/ruby
class ArrayMine < Array
   # Build a string from this array, formatting each entry
   # then joining them together.
   def join( sep = $, format = "%s" )
      x = collect {|item| sprintf( format, item ) }
      x.join(sep)
   end
end

p ArrayMine[1,2].join
moulon%

First it create an Array `x'
Then call #join for `x' (i.e. Array#join)

moulon% ./b.rb
"12"
moulon%

Guy Decoux

--
--- Shane Emmons <semmons99@gmail.com>