开发者

Calling a Method from Within a Ruby Class? (or is this rails magic)

I'm new to Ruby and working through some tutorials/screencasts. I've reached the section where they're discusisng the before_filter callback, and it's using some syntax that's a little weird for me. I don't know if it's a feature of ruby, of if it's some rails magic, and was hoping someone here could set me straight or point me in开发者_如何学运维 the right direction w/r/t the manual

This is a code fragment from the screencast I'm watching

class MachinesController < ApplicationController
    #...
    before_filter :login_required, :only => [:report]
    #...    
    def index
        #etc...
    end

    def login_required
        #etc...
    end
end

In the context of rails, I understand that before_filter is a callback that will fire login_required method when the report action is called. However, it's not clear to me what it is within the context of ruby. In other languages classes typically contain methods, properties, class variables and constants defined within the braces.

However, this looks like its a function call inside the class, and some experiments have show that you can put code in your class definitions and have it called when the program runs. Is this correct? If so, are there special contextual rules for code that's put inline into a class like that? (i.e. would the before_filter function in rails know what class it was called from) If not, what magic is rails doing here?


before_filter is a not actually a callback. It's a class method of ActiveRecord::Base that sets up a callback when you call it. So in this example:

before_filter :login_required, :only => [:report]

When the class is loaded, the method is called, and it adds :login_required to the filter chain for the report method.

The convention for these types of calls is to drop parens, but it would work just fine (and would be more easily identifiable as a method call) if you did this:

before_filter(:login_required, :only => [:report])


Unlike in some other languages, in Ruby the class can be modified at runtime and you can make function calls from within the class definition. So what's happening in this case is that you are calling the before_filter function, which then modifies the MachinesController class definition at runtime.

This is the mechanism which allows for the strikingly beautiful (to my eyes, at least) syntax that you get with Rails where it almost looks like you're using some sort of Domain Specific Language to describe your models. Stuff like the validates, has_many and belongs_to function calls on model classes.

My understanding is that this is called a macro and falls under the umbrella of meta programming. You can read more about this topic.


Ruby is so cool. You can definitely send messages from within a class block. As I understand it, what things like class do, other than the obvious, is control the identity of self. Thus, you should be able to call any method of the class or included modules from there.


I'm not sure exactly what your question is, but here's my interpretation:

before_filter

This is a class method call see ActionController

:login_required

This is a parameter to the before_filter method, and used as a callback using Object#send

:only => [:report]

This is an additional Hash parameter to before_filter see ActionController again.

I'd also suggest looking at the implementation of the before_filter method for insight.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜