【问题标题】:ruby class declaration questionruby 类声明问题
【发布时间】:2011-03-15 02:08:26
【问题描述】:

在 ruby​​ 中你可以拥有:

class ApplicationController < ActionController::Base
  before_filter :require_login
end

我只是想知道什么是 before_filter?它是来自 ActionController::Base 的方法吗?

如果我创建一个 ApplicationController 对象会发生什么?会运行 before_filter 方法吗?

谢谢!

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    是的,before_filter 是 ActionController::Base 上的一个方法。 before_filter 中指定的任何内容都将在调用操作之前运行。

    API 文档:http://api.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html#M000316

    编辑:

    当您直接写入类时,该代码会在类加载到解释器时执行。

    在 IRB 中输入:

    >> class Hello
    >> p "hello"
    >> end
    "hello"
    

    所以在您提到的情况下,ruby 会看到 before_filter 方法并尝试找到它。它开始在其类中查找,然后进入父级和父级的父级,依此类推,直到找到Object。在这种情况下,它将向上到 ActionController::Base 类并查找before_filter,然后向上到达类、模块和对象。

    >> ActionController::Base.class
    => Class
    >> ActionController::Base.class.superclass
    => Module
    >> ActionController::Base.class.superclass.superclass
    => Object
    >> ActionController::Base.class.superclass.superclass.superclass
    

    如果您愿意阅读,我强烈推荐MetaProgramming Ruby,它在解释对象模型方面做得比我做得更好。

    【讨论】:

    • 感谢您的回复。但我更想知道红宝石编程。在类的 open 中键入方法名是什么意思?
    【解决方案2】:

    link 解释得很好。基本上,Ruby 允许语法“糖”允许您定义将在特定时间运行的 ruby​​ 代码块。在before_filter 的情况下,它将在任何操作方法之前运行。

    【讨论】:

      【解决方案3】:

      当你在类定义中执行一个方法时,你实际上是在这样做:

      class ApplicationController
        self.before_filter
      end
      

      当 self 是类对象本身时(例如,在类定义中尝试 puts self

      例如,定义过滤器的穷人方式是

      class Filterable
      
          @@filters = []
      
          def self.before_filter(method_name)
            @@filters << method_name
          end
      
          def self.filters
            @@filters
          end
      
          def some_important_method
            self.class.filters.each do |method_name|
              # Halt execution if the return value of one of them is false or nil
              return unless self.send(method_name)
            end
            puts "I'm in some important method"
            # Continue with method execution
          end
      
      end
      
      class SomeClass < Filterable
      
        before_filter :first_filter
        before_filter :second_filter
      
        attr_accessor :x
      
        def initialize(x)
          @x = x
        end
      
        def first_filter
          puts "I'm in first filter"
          true
        end
      
        def second_filter
          puts "I'm in second filter"
          @x > 5
        end
      
      end
      

      你可以测试一下

      SomeClass.new(8).some_important_method
      # => I'm in first filter
      #    I'm in second filter
      #    I'm in some important method
      
      SomeClass.new(3).some_important_method
      # => I'm in first filter
      #    I'm in second filter
      

      希望澄清

      【讨论】:

        【解决方案4】:

        重要的是要知道,在 ruby​​ 上,类声明中的代码不是“特殊的”。

        这只是常规代码。您不仅限于定义方法和类变量 - 您的代码几乎可以做任何事情。

        例如,您可以执行以下操作:

        class MyClass
          print "wow"
        end
        

        结束后,打印“wow”并返回 nil。

        我再说一遍:你可以在类定义中包含很多你想要的东西。 包括修改类本身的调用方法

        这正是before_filter 所做的。它以“在调用此类上的任何方法之前,必须自动调用require_login”的方式修改类。

        【讨论】:

          猜你喜欢
          • 2011-06-11
          • 2022-01-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-04
          • 2014-11-05
          • 1970-01-01
          相关资源
          最近更新 更多