Passing params to Map method

Hi and thanks in advance for your help.
I have been pounding every Ruby and Rails book I can find, desperately
attempting to move beyond newbie status.My latest foray has taken me
into the native 2.0.2 Rails::Info module. I am reading what I think is
native ruby code but I can't seem to figure out what is being passed
to map and find. Could someone please explain (name, ) in the
following code?

Thanks again.

module Rails
  module Info
    mattr_accessor :properties

    class << (@@properties = [])
      def names
        map {|(name, )| name}
      end

      def value_for(property_name)
        find {|(name, )| name == property_name}.last rescue nil
      end
    end

Hi --

···

On Tue, 25 Mar 2008, Ruby Freak wrote:

Hi and thanks in advance for your help.
I have been pounding every Ruby and Rails book I can find, desperately
attempting to move beyond newbie status.My latest foray has taken me
into the native 2.0.2 Rails::Info module. I am reading what I think is
native ruby code but I can't seem to figure out what is being passed
to map and find. Could someone please explain (name, ) in the
following code?

Thanks again.

module Rails
module Info
   mattr_accessor :properties

   class << (@@properties = )
     def names
       map {|(name, )| name}
     end

     def value_for(property_name)
       find {|(name, )| name == property_name}.last rescue nil
     end
   end

find and map are not being passed any arguments; rather, they're being
given code blocks, and those blocks are being passed arguments.
(name,) is block parameter syntax for grabbing one element of an array
and putting it in name.

David

--
Upcoming Rails training from David A. Black and Ruby Power and Light:
   ADVANCING WITH RAILS April 14-17 New York City
   INTRO TO RAILS June 9-12 Berlin
   ADVANCING WITH RAILS June 16-19 Berlin
   CORE RAILS June 24-27 London (Skills Matter)
See http://www.rubypal.com for more info!

Thank you David,
I stand corrected (actually I'm sitting)

So.. I have been re-reading the best darn Ruby/Rails book on the
planet (Ruby for Rails of course! which I already read cover to cover
once) and I am still a bit confused but it's getting better.
Maybe someone could be so kind as to critique my comments below about
what I think is happening. I have been studying this little bit code
for about 6 .. no 8, hours and hopefully, I have most of it correct.
(personally I find it irritating when people ask questions without
putting any personal effort into finding the answers themselves)

module Rails
  module Info
    mattr_accessor :properties #module level property
assessor (getter and setter)
    class << (@@properties = []) #Open up Array class def to
add methods (class << object), object == an Array
      def names #define
Array.properties.names method
        map {|(name, )| name} #read code block to return
array comprised of first half of [name, value]
      end

      def value_for(property_name) #define
Array.properties.value_for("name param") method
        find {|(name, )| name == property_name}.last rescue nil
#return value part of [name, value] for sent name param
      end
    end #close Array class def

    class << self #:nodoc: #open "Info" class def to add
methods
      def property(name, value = nil) #define property "setter"
except the yield makes it a "getter"
        value ||= yield #if value is nil, yield name
to code block in names and value_for
        properties << [name, value] if value #push [name, value]
array into @@properties array
      rescue Exception #ignore error?
      end
      ...

What I think is happening is the new "Info.properties" accessor is
cleverly leveraging self.property as a method to both set a new
property into @@properties and to return (yield) just the name when
the parameter passed to the code block is just the first half of the
array (name, ). Just understanding that after 8 months and thousands
of hours and reading thousands of pages of books is really exciting
for me.

I am a little iffy on the "class << (@@properties = [])" opening up
the Array object, but it fits the rule.(class << object)

if that is true, it is pretty cool code. (it's pretty cool even if I
am wrong) Ruby has quite a learning curve, especially for a VB guy.

Thanks again.

From your description "block parameter syntax", someone might conclude
that this is something specific to blocks, but it's more generally the
syntax for destructuring an array. For example:

(x,) = [7,8,9] # x => 7
(x,y,z) = [7,8,9]

or even

x, = [7,8,9]

In the OP's example, I think map {|a| a[0] } is clearer, but if the
parameter is used multiple times, e.g. map {|a,| "#{a}-#{a}" }, then
assigning to 'a' initially is more concise.

···

On Mar 24, 11:57 pm, "David A. Black" <dbl...@rubypal.com> wrote:

...
find and map are not being passed any arguments; rather, they're being
given code blocks, and those blocks are being passed arguments.
(name,) is block parameter syntax for grabbing one element of an array
and putting it in name.

What I think is happening is the new "Info.properties" accessor is
cleverly leveraging self.property as a method to both set a new
property into @@properties and to return (yield) just the name when
the parameter passed to the code block is just the first half of the
array (name, ). Just understanding that after 8 months and thousands
of hours and reading thousands of pages of books is really exciting
for me.

Yep. Methods #names and #values_for are defined for the one instance
of Array only that is referenced by @@properties. So these are not
general methods. But they rely on methods defined in Array and
Enumerable to do their job. Basically they seem to rely on the fact
that @@properties contains arrays with exactly two elements - the
first one used as property name and the second one as property value.
During iteration (i.e. map, find) on the array only the first is
assigned a block parameter (small optimization because the second one
is not needed). That's it basically. This is the usual pattern
matching that Ruby applies to multiple assignments:

irb(main):001:0> (a,(b,c),d)=1,2,3,4,5
=> [1, 2, 3, 4, 5]
irb(main):002:0> a
=> 1
irb(main):003:0> b
=> 2
irb(main):004:0> c
=> nil
irb(main):005:0> d
=> 3
irb(main):006:0> (a,(b,c),d)=1,[2,3],4,5
=> [1, [2, 3], 4, 5]
irb(main):007:0> a
=> 1
irb(main):008:0> b
=> 2
irb(main):009:0> c
=> 3
irb(main):010:0> d
=> 4

What makes this a bit hard to read is that assignment to @@properties
and the class<<@@properties are lumped into one statement.

I am a little iffy on the "class << (@@properties = )" opening up
the Array object, but it fits the rule.(class << object)

if that is true, it is pretty cool code. (it's pretty cool even if I
am wrong) Ruby has quite a learning curve, especially for a VB guy.

Yeah, it seems VB is a bad place to start learning to program. :slight_smile:

Kind regards

robert

···

2008/3/26, Ruby Freak <twscannell@gmail.com>:

--
use.inject do |as, often| as.you_can - without end