Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > What does this construct mean?

Reply
Thread Tools

What does this construct mean?

 
 
Casper
Guest
Posts: n/a
 
      07-16-2005
1. class MyController < ActionController::Base
2. helper :my_helper
3. end

I see this construct in Ruby on Rails a lot, and I don't know what is
going on in line 2.

Is this invoking a method called "helper" with the argument
":my_helper"? And if so, when does this get invoked?

Thanks.

 
Reply With Quote
 
 
 
 
Devin Mullins
Guest
Posts: n/a
 
      07-16-2005
Casper wrote:

>1. class MyController < ActionController::Base
>2. helper :my_helper
>3. end
>
>I see this construct in Ruby on Rails a lot, and I don't know what is
>going on in line 2.
>
>Is this invoking a method called "helper" with the argument
>":my_helper"? And if so, when does this get invoked?
>
>Thanks.
>
>

You are on the money. I will attempt to explain, but you should read the
PickAxe for the full Ruby goodness.

class sdgksjdgk
...
end

Is just a way of scoping your code. In particular, it redefines self, it
creates a new lexical scope (that is, a new binding for local
variables), it tells class variables (@@foo) where to hook up to, and it
tells method definitions where to hook up to. Run `ruby -e"p self" ` and
you'll discover that you're always inside a class...end block.

So
class Blob
puts "Hello!"
end

Prints "Hello!" How does it do that? Well, you're trying to call "puts"
which really means you're trying to call "self.puts". What's self? Well,
let's find out:

a = class Blob
self #like defs and blocks, class returns the last thing evaluated
end
=> Blob
a.class
=> Class

Self is the Class object named Blob. So when you type "puts" inside a
class block, you're calling the instance method Blob.puts. Where does
it get puts from? Well, Blob is a Class, and Class inherits Object, and
Object includes Kernel, and Kernel has a puts method defined on it.

When you write
class Blob
def murh
puts "Hello!"
end
end
you're referring to an entirely different self.puts, of course. When
"murh" actually gets invoked, self will be the Blob instance it gets
invoked on, instead of the Class instance named Blob. But when the
method is actually defined, Ruby knows to define it as an instance
method of whatever class...end block it's inside.

So, when you call helper :my_helper, bingo, you're calling a method.
Specifically, Blob.helper. Not Blob#helper, which is the instance
method, where self would be some instance of Blob -- rather this
something akin to Class#helper. (When I say "something akin to" I'm
referring to singleton classes. That's a whole 'nother email, though.)

Where is it getting helper from? Well, in short, it's getting it from
ActionController::Helpers::ClassMethods in action_controller/helpers.rb.
The long version involves explaining what singleton classes are.

Hope that helps.

Sidenote - Adanced Rubyage:

Earlier I said that class...end does more than redefine self. This is
important. Notice that, of the following two, the first works but the
second doesn't:

#1:
class Moo
@@fun = 0
def Moo.fun
@@fun += 1
puts @@fun
end
end

#2:
class Moo
@@fun
end
def Moo.fun
@@fun += 1
puts @@fun
end

Here's another example where the scope of a given thing is not dependent
on self, but dependent on what class...end block I'm inside.

class Borg
def blong
def frooz
puts 'Hi!'
end
end
end
a = Borg.new; b = Borg.new
a.frooz #=> Error
a.blong
a.frooz #=> Hi!
b.frooz #=> Hi!

If the 'def' keyword were dependent upon self, then the above would not
work. Notice that, when 'def blong' is run, self is the Class object
named Borg. When 'def frooz' is run, self is the Borg object assigned to a.

Rather, a 'def' keyword is tied to what class it's in. See the following
wacky example:

class A
end

class B
def A.moo
def moo
puts 'mooo'
end
end
end

a = A.new
b = B.new

A.moo

a.moo #=> Error
b.moo #=> mooo

But if you find a legitimate reason to do **** like that, please let me
know. I'm quite curious.

BTW, if you read a couple of threads back, class...end isn't the only
way to establish such a context. There's also Class.new and
Module#class_eval -- running 'def' inside those is like running it
inside a proper class...end block.

Oh boy. I'm feeling kinda light-headed now...

Devin



 
Reply With Quote
 
 
 
 
Daniel Brockman
Guest
Posts: n/a
 
      07-16-2005
"Casper" <(E-Mail Removed)> writes:

> 1. class MyController < ActionController::Base
> 2. helper :my_helper
> 3. end
>
> I see this construct in Ruby on Rails a lot, and I don't know what is
> going on in line 2.
>
> Is this invoking a method called "helper" with the argument
> ":my_helper"?


Exactly.

> And if so, when does this get invoked?


When that part of the code is reached.

Class bodies are executed just like normal code, with `self' bound to
the class object, so the following example code

puts 123
class Foo ; puts self end
puts 456

produces the following output:

123
Foo
456

--
Daniel Brockman <(E-Mail Removed)>

So really, we all have to ask ourselves:
Am I waiting for RMS to do this? --TTN.



 
Reply With Quote
 
Casper
Guest
Posts: n/a
 
      07-18-2005
Devin Mullins wrote:
> Casper wrote:
>
> >1. class MyController < ActionController::Base
> >2. helper :my_helper
> >3. end
> >
> >I see this construct in Ruby on Rails a lot, and I don't know what is
> >going on in line 2.
> >
> >Is this invoking a method called "helper" with the argument
> >":my_helper"? And if so, when does this get invoked?
> >
> >Thanks.
> >
> >

> You are on the money. I will attempt to explain, but you should read the
> PickAxe for the full Ruby goodness.
>

<snip>

Thanks for the detailed explanation.

I guess two reasons that I had difficult figuring out are (1) Ruby
allows executable stuff to go where I expect to see declarations, but
moreover (2) Ruby allows method calls to have their arguments
delineated with or without parentheses. In particular, I don't
understand the why you would want this. Is there a good motivation to
allow it?

 
Reply With Quote
 
Ara.T.Howard
Guest
Posts: n/a
 
      07-18-2005
On Tue, 19 Jul 2005, Casper wrote:

> Devin Mullins wrote:
>> Casper wrote:
>>
>>> 1. class MyController < ActionController::Base
>>> 2. helper :my_helper
>>> 3. end
>>>
>>> I see this construct in Ruby on Rails a lot, and I don't know what is
>>> going on in line 2.
>>>
>>> Is this invoking a method called "helper" with the argument
>>> ":my_helper"? And if so, when does this get invoked?
>>>
>>> Thanks.
>>>
>>>

>> You are on the money. I will attempt to explain, but you should read the
>> PickAxe for the full Ruby goodness.
>>

> <snip>
>
> Thanks for the detailed explanation.
>
> I guess two reasons that I had difficult figuring out are (1) Ruby
> allows executable stuff to go where I expect to see declarations, but
> moreover (2) Ruby allows method calls to have their arguments
> delineated with or without parentheses. In particular, I don't
> understand the why you would want this. Is there a good motivation to
> allow it?


the best reason is the example you posted - one can make methods which read
like syntax additions/declarations. the built-in

class C
attr_accessor 'a'
end

which (just in case you didn't know) automatically generate accessor methods
for C objects as in

obj = C::new
obj.a = 42
p obj.a #=> 42

and this reads really nicely. another good reason to ignore parens is for
boolean methods like

if array.emtpy?
array << 42
end

i think most would agree that this looks better than

if array.emtpy?()

and of course

array << 42

looks a heck of a lot better than

array.<<(42)

remember, even '<<' is a method in ruby! then there are always methods like

element = array.pop

which just reads quite nicely without parens and last, but not least, those of
us who've detest any extra chars in code like '$', ';', and even parens. they
don't call it 'poetry' mode for nothing

cheers.

-a
--
================================================== =============================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| My religion is very simple. My religion is kindness.
| --Tenzin Gyatso
================================================== =============================

 
Reply With Quote
 
David A. Black
Guest
Posts: n/a
 
      07-18-2005
Hi --

On Tue, 19 Jul 2005, Ara.T.Howard wrote:

> which just reads quite nicely without parens and last, but not least, those
> of
> us who've detest any extra chars in code like '$', ';', and even parens.
> they
> don't call it 'poetry' mode for nothing


Actually, they do This came up on IRC recently, and I still don't
know the answer: why is the non-use of parentheses referred to as
"poetry mode", when plenty of poems contain parentheses? It's never
made any sense to me.


David

--
David A. Black
http://www.velocityreviews.com/forums/(E-Mail Removed)


 
Reply With Quote
 
Charles Steinman
Guest
Posts: n/a
 
      07-18-2005

Ara.T.Howard wrote:
> the best reason is the example you posted - one can make methods which read
> like syntax additions/declarations. the built-in
>
> class C
> attr_accessor 'a'
> end
>
> which (just in case you didn't know) automatically generate accessor methods
> for C objects as in
>
> obj = C::new
> obj.a = 42
> p obj.a #=> 42
>
> and this reads really nicely. another good reason to ignore parens is for
> boolean methods like
>
> if array.emtpy?
> array << 42
> end
>
> i think most would agree that this looks better than
>
> if array.emtpy?()


Or even worse if array is gotten through an accessor, in which case
you'd have "if array().empty?()", which is just rancid.

 
Reply With Quote
 
Ara.T.Howard
Guest
Posts: n/a
 
      07-18-2005
On Tue, 19 Jul 2005, David A. Black wrote:

> Hi --
>
> On Tue, 19 Jul 2005, Ara.T.Howard wrote:
>
>> which just reads quite nicely without parens and last, but not least, those
>> of
>> us who've detest any extra chars in code like '$', ';', and even parens.
>> they
>> don't call it 'poetry' mode for nothing

>
> Actually, they do This came up on IRC recently, and I still don't
> know the answer: why is the non-use of parentheses referred to as
> "poetry mode", when plenty of poems contain parentheses? It's never
> made any sense to me.


parens, in ruby anyhow, don't do anything except specify precendence to the
interpreter - much as in mathematics. imagine if we all wrote (in hand on
paper - not in code)

a = (b + (c / 2))

it would be all line noise. i think the 'poetry' bit makes sense since poetry,
when compared to 'normal' writing is clearly an attempt to distill an ideal,
feeling, emotion, etc. into a few select words arranged to maximize there
meaning - and yet leave room for interpretation. punctuation is for clarity
where it is needed but obfusicates otherwise (as the example above shows i
think). in this sense using minimal (not none!) punctuation seems congruent
with the idea of writing poetry - at least to me. consider:

My legacy -
What will it be?
Flowers in spring,
The cuckoo in summer,
And the crimson maples
Of autumn ...

or

My legacy -
What will it be?
Flowers in spring,
The cuckoo in summer,
And the crimson maples (Of autumn).

- Ryokan (1758-1831)

kind regards.

-a
--
================================================== =============================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| My religion is very simple. My religion is kindness.
| --Tenzin Gyatso
================================================== =============================



 
Reply With Quote
 
Ara.T.Howard
Guest
Posts: n/a
 
      07-18-2005
On Tue, 19 Jul 2005, Charles Steinman wrote:

>
> Ara.T.Howard wrote:
>> the best reason is the example you posted - one can make methods which read
>> like syntax additions/declarations. the built-in
>>
>> class C
>> attr_accessor 'a'
>> end
>>
>> which (just in case you didn't know) automatically generate accessor methods
>> for C objects as in
>>
>> obj = C::new
>> obj.a = 42
>> p obj.a #=> 42
>>
>> and this reads really nicely. another good reason to ignore parens is for
>> boolean methods like
>>
>> if array.emtpy?
>> array << 42
>> end
>>
>> i think most would agree that this looks better than
>>
>> if array.emtpy?()

>
> Or even worse if array is gotten through an accessor, in which case
> you'd have "if array().empty?()", which is just rancid.


amen brother.

-a
--
================================================== =============================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| My religion is very simple. My religion is kindness.
| --Tenzin Gyatso
================================================== =============================

 
Reply With Quote
 
Daniel Brockman
Guest
Posts: n/a
 
      07-18-2005
"Ara.T.Howard" <(E-Mail Removed)> writes:

> consider:
>
> My legacy -
> What will it be?
> Flowers in spring,
> The cuckoo in summer,
> And the crimson maples
> Of autumn ...
>
> or
>
> My legacy -
> What will it be?
> Flowers in spring,
> The cuckoo in summer,
> And the crimson maples (Of autumn).
>
> - Ryokan (1758-1831)


Impressively fitting example!

--
Daniel Brockman <(E-Mail Removed)>

So really, we all have to ask ourselves:
Am I waiting for RMS to do this? --TTN.



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Behavior of if construct in switch case defualt construct. Mukesh C Programming 4 03-26-2010 12:38 PM
what does the followed_by construct mean? Dan Quach Ruby 3 01-21-2010 06:32 AM
Does the following construct qualify as overloading on return type ? Nikhil.S.Ketkar@gmail.com C++ 0 08-15-2008 08:35 AM
The extern "C" construct - does it allow the use of C-style (int-based) enums? Chris Cahoon C++ 3 06-13-2007 08:50 AM
How does vector construct/destruct objects? Lasse Skyum C++ 6 10-29-2003 10:24 AM



Advertisments