Modules: The Secret H method

Hello!

I am having a hard time using modules. It seems that to successfully
use one, you
need to know all sorts of obscure things about the environment that
the module expects.

For example, I want to use Webby::Helpers::UrlHelper. This module
refers to a @pages
variable that I have to provide in the class that "include"s the
module. That is not so
hard, but I can only find that requirement via experimentation. If I
provide the @pages
variable in my class, I then find that the module refers to a method
“h”. I know rails
has a helper method “h”, but cannot otherwise find one, despite all my
grep -ir “def h” on the entire standard library and all gems (well,
“rack” has such
a method too, but Webby never uses rack AFAIK).

So is this how people normally use modules, or am I doing something
stupid?
How is anyone supposed to know the possibly highly complex
requirements of a module

  • or does it fall to documentation again?

There’s a similar problem with calling any methods that take
parameters in Ruby -
how can you get a list of all the methods that will be applied to the
object you passed
in? Either the documentation says “pass in a string” and then you are
expected
to pass in something that responds to ALL of string’s methods, or the
documentation
must list every method applied, along with its signature. All the
documentation I have
seen uses option A: it mentions the class to pass in. Which renders
duck-typing shot,
unless I descend from that class perhaps?

BTW: where can I find the secret “h” method?

Les

Leslie V. wrote:

Hello!

I am having a hard time using modules. It seems that to successfully
use one, you
need to know all sorts of obscure things about the environment that
the module expects.

For example, I want to use Webby::Helpers::UrlHelper. This module
refers to a @pages
variable that I have to provide in the class that "include"s the
module. That is not so
hard, but I can only find that requirement via experimentation. If I
provide the @pages
variable in my class, I then find that the module refers to a method
“h”. I know rails
has a helper method “h”, but cannot otherwise find one, despite all my
grep -ir “def h” on the entire standard library and all gems (well,
“rack” has such
a method too, but Webby never uses rack AFAIK).

So is this how people normally use modules, or am I doing something
stupid?
How is anyone supposed to know the possibly highly complex
requirements of a module

  • or does it fall to documentation again?

There’s a similar problem with calling any methods that take
parameters in Ruby -
how can you get a list of all the methods that will be applied to the
object you passed
in? Either the documentation says “pass in a string” and then you are
expected
to pass in something that responds to ALL of string’s methods, or the
documentation
must list every method applied, along with its signature. All the
documentation I have
seen uses option A: it mentions the class to pass in. Which renders
duck-typing shot,
unless I descend from that class perhaps?

BTW: where can I find the secret “h” method?

Les

This is ruby code:

puts ‘hello’

–output:–
hello

This is also a ruby code:

#my_own_language.rb:
def puts(x)
print “goodbye\n”
end

#my_program.rb
require 'my_own_language.rb

puts ‘hello’

–output:–
goodbye

How would you respond to someone who constantly asks why puts in Ruby
always outputs ‘goodbye’?

How would you respond to someone who constantly asks why puts in Ruby
always outputs ‘goodbye’?

I would say “because you redefined puts”.

But this does not help me find the “h” method. It also does not help
me to discover the needs of a module or method.

I then find that the module refers to a method
“h”. I know rails
has a helper method “h”, but cannot otherwise find one, despite all my
grep -ir “def h” on the entire standard library and all gems

That’s because h is an alias for html_escape (defined in ERB::Util).
Do grep “alias h html_escape” on your standart library and you will
most likely find it.
Take a look at
actionpack/lib/action_view/template_handlers/erb.rb in rails and
/usr/lib/ruby/1.8/erb.rb in ruby standard lib (your paths may differ).

Regards,
Rimantas

From my experience with Ruby I can say that people often just overuse
Ruby modules (and generally all Ruby metaprogramming stuff and dynamic
capabilities). I think that using modules should be similar to
Enumerable. Just include it, define one (two) special methods (each,
<=>) and you have some functionality. But Ruby programmers (I’m Ruby
programmer to :)) tend to use modules to distribute class
implementations to diffrent part (so they use many instance variables
and internal part of desired class).

For example, when I want to find what methods are in controller
instance (rails) I can’t just go to ActionController::Base and list
all methods because that class has many included modules (and many of
them are included outside class). I’m not complaining about Ruby
itself, rather about programmers :).


Rados³aw Bu³at

http://radarek.jogger.pl - mój blog

Leslie V. wrote:

How would you respond to someone who constantly asks why puts in Ruby
always outputs ‘goodbye’?

I would say “because you redefined puts”.

But this does not help me find the “h” method.

Then consider directing your questions to whoever wrote
my_own_language.rb or the people who use it frequently.

On Feb 19, 2008 1:58 PM, Rimantas L. [email protected] wrote:

/usr/lib/ruby/1.8/erb.rb in ruby standard lib (your paths may differ).
Ah, thank-you very much, that helps a lot.

2008/2/19 Rados³aw Bu³at [email protected]:

For example, when I want to find what methods are in controller
instance (rails) I can’t just go to ActionController::Base and list
all methods because that class has many included modules (and many of
them are included outside class). I’m not complaining about Ruby
itself, rather about programmers :).

I agree. I very often have to read a library author’s code to see how
to use things. Though I am not complaining about Ruby or the programmers

I’m more interested in ways people use to overcome these problems.

For example, perhaps people make probe objects and send them in to
record the methods that the target function tries to call on them.
But that doesn’t help too much because behavior changes based on
the spy object’s responses.

Perhaps there’s a way to use the Ruby parser, or an intelligent
interpreter
to enumerate most of the methods a that will be called on a parameter.

Les

On Feb 19, 2008 2:48 PM, 7stud – [email protected] wrote:

Leslie V. wrote:

How would you respond to someone who constantly asks why puts in Ruby
always outputs ‘goodbye’?

I would say “because you redefined puts”.

But this does not help me find the “h” method.

Then consider directing your questions to whoever wrote
my_own_language.rb or the people who use it frequently.

Yes, the ‘h’ method is in ERB. ERB is part of standard Ruby.
This is the Ruby mailing list.

On Feb 18, 11:43 pm, Leslie V. [email protected] wrote:

module. That is not so
hard, but I can only find that requirement via experimentation. If I
provide the @pages
variable in my class

This, honestly is a sign of bad design. Modules should be designed so
that the including class only needs to define a few–if any–methods to
be used by that module, and they should be clearly documented in the
module. Accessing instance variables that are not “owned” by the
module is just asking for trouble. No, I don’t think /you’re/ doing
something wrong–your just running into a poorly designed module.

There’s a similar problem with calling any methods that take
parameters in Ruby -
how can you get a list of all the methods that will be applied to the
object you passed
in?

Other than by looking at the code, you can’t, really. I suppose you
could always pass in some sort of “recorder” object to list out the
method calls, but I’m not sure the returns would be worth it in most
cases. Honestly, this is where a good automated test suite will help
you. Just verify in your tests that whatever kind of object you’re
actually going to pass in doesn’t cause any errors.


Regards,

John W.