What does this construct mean?

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.

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

"Casper" <caspertonka@yahoo.com> 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 <daniel@brockman.se>

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

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 :wink:

cheers.

-a

···

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?

--

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

===============================================================================

Probably because of the first program people see:

    puts "Hello, world!"

versus:

    puts("Hello, world!")

However, even this simple example highlights a problem. Insert a space
between puts and ( and you get a warning:

    $ ruby -we 'puts ("Hello")'
    -e:1: warning: (...) interpreted as grouped expression
    Hello

    $ ruby -we 'puts ("Hello","world")'
    -e:1: warning: don't put space before argument parentheses
    Hello
    world

Even though (a,b,c) is not a valid expression when standing alone, the Ruby
interpreter has difficulty deciding whether (a) is an expression wrapped in
parentheses, or a method call argument list wrapped in parentheses.

To see where it makes a difference, try these:

    $ ruby -e 'puts ("a"), ("b")'
    $ ruby -e 'puts("a"), ("b")'

    $ ruby -e 'puts (3+4).abs'
    $ ruby -e 'puts(3+4).abs'

I think the space-sensitive behaviour is driven by this last case: i.e. that
"method1 (expr).method2" should be parsed as "method1( (expr).method2 )"
whereas "method1(expr).method2" is "(method1(expr)).method2"

Regards,

Brian.

···

On Tue, Jul 19, 2005 at 02:50:54AM +0900, Casper wrote:

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?

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 :wink:

Actually, they do :slight_smile: 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
dblack@wobblini.net

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.

To be honest, that the following two lines
    puts (3+4).abs
    puts(3+4).abs
are semantically different *feels* very broken to me. My gut says that
this is a vector for confusion and the introduction of bugs.

That being said, I'm not ready to defend the statement that it *is*
broken. I'll try to live with it for a while and see if I come around.
:slight_smile:

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

···

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 :wink:

Actually, they do :slight_smile: 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.

--

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

===============================================================================

amen brother.

-a

···

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.

--

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

===============================================================================

David A. Black wrote:

Actually, they do :slight_smile: 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.

Without researching it at all, I'd guess that it traces back to an April Fool's Joke in comp.lang.perl that was subsequently described in Chapter 7 of the Camel Book as "Perl Poetry" (http://www.unix.org.ua/orelly/perl/prog3/ch27_02.htm\). Larry feigned innocence, but I never bought it.

Steve

David A. Black wrote:

Hi --

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 :wink:

Actually, they do :slight_smile: 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.

I believe it's a reference to the tendency of modern poetry
to omit punctuation in general, particularly the imitators
of E. E. Cummings. (And yes, he frequently did use punctuation,
as well as capital letters.)

Hal

···

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

* Casper <casper.tonka@gmail.com> [2005-07-21 09:20:55 +0900]:

To be honest, that the following two lines
    puts (3+4).abs
    puts(3+4).abs
are semantically different *feels* very broken to me. My gut says that
this is a vector for confusion and the introduction of bugs.

I think it depends on what binding you prefer most.
Consider

  method_that_returns_some_string(arg).upcase!

I think this does what one would expect. It is going
to upcase the returned string.
But, if it is written with a space after the method name

  method_that_returns_some_string (arg).upcase!

you suggest that this should bind the same as if the space
were not present. That means that constructs like

  sqrt (-2).abs

could not be written without an extra set of ()'s.
Doesn't this rule that ()'s after a method
are always bound to the method imply that ()'s
are essentially always needed, especially if
any argument uses parens?

  sqrt ( (-2).abs )
This clearly needs the outer parens.

  method_take_two_args arg1, (arg2+arg3)
While this may be valid.

  method_take_two_args (arg1+arg2), arg3
But, this would not work and would need to be written as:

  method_take_two_args ((arg1+arg2), arg3)
or
  method_take_two_args (arg1+arg2, arg3)

Ugh. The more I look into this, the more I like the elegance
of Ruby.

···

--
Jim Freeze

In Ruby, parenthesis are sometimes optional, just as a convenience to you the coder. In any midly complex case, just go ahead and include them and you never need to worry about this again. I leave parenthesis off:

1. No parameter attributes: object.attr
2. Boolean method tests: if object.is_a? Whatever
3. Simple IO: puts "Printing this out #{(3 + 4).abs}..."

The rest of the time, just add them. If you have to stop and think for even a second, it's time to add some parenthesis. Then you never need worry again.

James Edward Gray II

···

On Jul 20, 2005, at 7:20 PM, Casper wrote:

To be honest, that the following two lines
    puts (3+4).abs
    puts(3+4).abs
are semantically different *feels* very broken to me. My gut says that
this is a vector for confusion and the introduction of bugs.

That being said, I'm not ready to defend the statement that it *is*
broken. I'll try to live with it for a while and see if I come around.
:slight_smile:

"Ara.T.Howard" <Ara.T.Howard@noaa.gov> 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 <daniel@brockman.se>

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

Hi --

Hi --

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 :wink:

Actually, they do :slight_smile: 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).

I think you'd have to go beyond (b + (c / 2)) to illustrate really
obscure or obfuscated punctuation :slight_smile: In any case, one has to
conclude reluctantly that readability and clarity end up being in the
eye of the beholder. (I wish I could believe it were otherwise, but
the things done in Ruby in the name of clarity are often so unclear to
me as to force me to that conclusion :slight_smile: The whole "poetry" thing, I
think, comes from something else. I don't think it's just a
compliment (calling something "poetry" because it's clear and free of
non-technically-mandated punctuation), but it can't really be about
clarity in a transcendent sense.

My favorite example of (what to me is) great unclarity introduced by
the absence of optional parentheses is:

   def a b, c = 1

Of course I know enough to parse it visually, but I don't take it in
as readily in a glance as:

   def a(b,c=1)

I'm not out to convince other people that their brains work the same
way mind does; but I'd definitely rule out a universal "less
punctuation makes things clearer" axiom, based on this and other
examples.

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

Well, you could put a bright red dot on the Mona Lisa and conclude
that red was a bad color for art because it ruined the painting :slight_smile: I
don't think parentheses used by an author are a determinant of a
text's status as poetry or prose.

David

···

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

On Tue, 19 Jul 2005, David A. Black wrote:

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

--
David A. Black
dblack@wobblini.net

Hi --

···

On Tue, 19 Jul 2005, Steven Jenkins wrote:

David A. Black wrote:

Actually, they do :slight_smile: 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.

Without researching it at all, I'd guess that it traces back to an April Fool's Joke in comp.lang.perl that was subsequently described in Chapter 7 of the Camel Book as "Perl Poetry" (http://www.unix.org.ua/orelly/perl/prog3/ch27_02.htm\). Larry feigned innocence, but I never bought it.

I remember that example, though it still doesn't explain the equation
of the idea of "poetry mode" with lack of parentheses.

Oh well -- my curiosity stops short of being willing to trace ten
years of evolution of usage, so I guess it will remain a mystery :slight_smile:

David

--
David A. Black
dblack@wobblini.net

Ara.T.Howard wrote:
...

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.

Interesting. I think poetry (when done well) elicits meaning from the reader; it is a trigger, a catalyst, and the "meaning" of a poem varies not only for each person, but for any given person at different times.

To my mind, code poetry would never run the same way on different machines, and indeed would never run quite the same way on the same machine, yet would still impart something of appropriate value each time.

James

···

--

http://www.ruby-doc.org - The Ruby Documentation Site
http://www.rubyxml.com - News, Articles, and Listings for Ruby & XML
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys

I think you'd have to go beyond (b + (c / 2)) to illustrate really obscure
or obfuscated punctuation :slight_smile: In any case, one has to conclude reluctantly
that readability and clarity end up being in the eye of the beholder. (I
wish I could believe it were otherwise, but the things done in Ruby in the
name of clarity are often so unclear to me as to force me to that conclusion
:slight_smile: The whole "poetry" thing, I think, comes from something else. I don't
think it's just a compliment (calling something "poetry" because it's clear
and free of non-technically-mandated punctuation), but it can't really be
about clarity in a transcendent sense.

My favorite example of (what to me is) great unclarity introduced by the
absence of optional parentheses is:

def a b, c = 1

Of course I know enough to parse it visually, but I don't take it in as
readily in a glance as:

def a(b,c=1)

yes. that's much better.

I'm not out to convince other people that their brains work the same way
mind does; but I'd definitely rule out a universal "less punctuation makes
things clearer" axiom, based on this and other examples.

oh me too! i just tend to use less than some. it takes time, but after a
small adjustment period less can sometimes be more.

Well, you could put a bright red dot on the Mona Lisa and conclude that red
was a bad color for art because it ruined the painting :slight_smile: I don't think
parentheses used by an author are a determinant of a text's status as poetry
or prose.

agreed. still - sometimes being __totally__ clear makes things less clear, if
you know what i mean.

cheers.

-a

···

On Tue, 19 Jul 2005, David A. Black wrote:
--

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

===============================================================================