Why Class decls and API docs don't Match

Anybody who’s done any Ruby on Rails will have seen, edited, or
constructed the following which is suggestive of a general Ruby issue:

class ApplicationController < ActionController::Base
layout “standard”
end

Now nevermind that to a JAVA/Eiffel/C/C++ programmer the naked method
call to layout() should be illegal because it’s not inside a function
block. I can get over that.

Just ask yourself this: Where is layout() defined?

  1. It’s in ApplicationController? No. What you see IS the complete
    definition. No layout() there.
  2. It’s in the super class ActionController::Base. No. Check the docs.
    Read the gem source. There’s no layout() in ActionController::Base.

So where is it?

Get this: it’s in ApplicationController::Layout::ClassMethods. But
ApplicationController, Layout, ClassMethods are all modules. And while
Base is a class inside ApplicationController I don’t see where it
includes ApplicationController::Layout::ClassMethods.

Bottom line: how is layout() in scope for ApplicationController? And,
as appears to the case, if layout is callable from any
ActionController::Base heir, why in the heck isn’t it in the docs for
ActionController::Base?

When I go and read the docs for ActionController::Base, I want to know
ALL the stuff it can do. That is is just plain common sense to in
most any other OO language. Ruby appears to buck this norm.

  1. It’s in the super class ActionController::Base. No. Check the docs.
    Read the gem source. There’s no layout() in ActionController::Base.

It’s still true: Look at http://api.rubyonrails.com/ and click on the
class. There’s NO LAYOUT().

But this comment:

Read the gem source. There’s no layout() in ActionController::Base.
IS POSSIBLY WRONG. I made my original comments based on the 60 or so
.rb files inside
this directory:

/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller

but if I had looked at this file:

/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller.rb

I see something approximating a class definition … but not exactly:

ActionController::Base.class_eval do
. . .
include ActionController::Flash
include ActionController::Filters
include ActionController::Layout
. . .
end

But there’s still no: include ActionController::Layout::ClassMethods.

The open nature of Ruby — the ability to chage module or class
interfaces in many, many files only makes my original question more
important:

HOW DO YOU KNOW, BOTTOM LINE, AFTER ALL THE VARIOUS FILES ARE
CONSIDERED, WHAT A CLASS DOES?

I still don’t know how ApplicationController::Base can call layout(). I
still can’t understand why it’s not in the doc as common sense demands.

On Wed, 18 Oct 2006 15:33:35 -0700, gsm.beamon wrote:

ApplicationController, Layout, ClassMethods are all modules. And while
Base is a class inside ApplicationController I don’t see where it
includes ApplicationController::Layout::ClassMethods.

That’s taken care of in the hook ApplicationController::Layout.included.

Bottom line: how is layout() in scope for ApplicationController? And,
as appears to the case, if layout is callable from any
ActionController::Base heir, why in the heck isn’t it in the docs for
ActionController::Base?

When defining a module, the methods defined in the module are included
into the class as instance methods when you use the “include” keyword.
Hwever, the module methods defined with a construction like

module ApplicationController::Layout
def self.layout
#foo
end
end

would not be included as class methods, so we do the next best thing
which
is to put all of these class methods into their own module, and put them
in the right place with the hook

module ApplicationController::Layout
def self.included(other)
other.extend(ClassMethods)
end
end

I nevertheless do not know what the rationale is for not bringing
along the class methods of a module along with the instance methods when
the module is included in a class.

–Ken

Crystal balls help. I feel the pain. Sadly enough, irb, listing methods
of an object interactively, and then wading through docs to guess where
they are defined are your only salvation. Basically, hope you never have
to use more of libraries like this than you can keep in your head after
learning them, or that someone does Cruel and Unusual things to rdoc to
let it figure out these shenanigans.

Thank you.

Ruby Community: why doesn’t RDOC tell you all the includes or requires?
I mean if ApplicationController::Base said that it included files
<…> then I could have put two
and two together.

My only problem — which I belatedly solved and which was immediately
pointed out
by another poster — is that I was looking in the wrong files. Had I
kept on looking I
would have found even more files that evenutally defined the class and
included
ApplicationController::Layout which presumbably includes
ApplicationController::Layout::
ClassMethods. And volia there’s layout().

The connection is important. This seems obvious to me. But other
posters have
said, “Hey, I found it not problem in …/layout.rb. So what’s the
deal?” The deal is
that this:

class ApplicationController < ActionController::Base
layout “standard”
end

Why is should anybody jump and then why is it correct to jump from
ActionController::Base to ActionController::Layout::ClassMethods per
…/layout.rb?
That isn’t answered by merely pointing …/layout.rb.

[email protected] wrote:

HOW DO YOU KNOW, BOTTOM LINE, AFTER ALL THE VARIOUS FILES ARE
CONSIDERED, WHAT A CLASS DOES?

Crystal balls help. I feel the pain. Sadly enough, irb, listing methods
of an object interactively, and then wading through docs to guess where
they are defined are your only salvation. Basically, hope you never have
to use more of libraries like this than you can keep in your head after
learning them, or that someone does Cruel and Unusual things to rdoc to
let it figure out these shenanigans.

David V.

[email protected] wrote:

Ruby Community: why doesn’t RDOC tell you all the includes or requires?
I mean if ApplicationController::Base said that it included files
<…> then I could have put two
and two together.

It does, most of the time.
Just not when the code in question uses various ‘tricky’ techniques to
do so.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs