Passing params to Map method

R

Ruby Freak

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
 
D

David A. Black

Hi --

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!
 
R

Ruby Freak

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.
 
R

Robert Klemme

2008/3/26 said:
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. :)

Kind regards

robert
 
B

Brian Adkins

...
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.

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top