ruby clases里面的语法是什么?

时间:2015-10-22 08:27:10

标签: ruby-on-rails ruby

class ApplicationController < ActionController::Base
  protect_from_forgery #What is this syntax? When is this executed and how to create one?
end

class Comment < ActiveRecord::Base
  belongs_to :post
  attr_accessible :body, :commenter, :post
end

在第一种情况下,我理解ApplicationController是ActionController模块中名为Base的新Derived类。下一行会发生什么? protect_from_forgery是基类或模块ActionController中的方法吗?这叫什么?我无法在ruby类文档中找到它。我尝试在基类中创建一个方法,但是遇到了如下错误。如何创建可在类中使用的特殊命令?

class Base
  def foo
    @name = "foo"
  end
end

class Der < Base
  foo
  def bar
    @dummy = "bar"
  end
end

错误:

expr1.rb:62:in `<class:Der>': undefined local variable or method `foo' for Der:Class (NameError)
    from expr1.rb:61:in `<main>'

5 个答案:

答案 0 :(得分:3)

protect_from_forgeryActionController::Base中包含的其中一个模块中定义的类方法,当您从ActionController::Base继承时,它可供子类使用。

Rails中的这种方法有时被称为&#34;宏&#34;因为它们是类方法,可以启用某些特定功能(有时也使用元编程来定义额外的方法或帮助程序)。实际上,术语&#34;宏观&#34;是不正确的,因为Ruby没有宏。它们只不过是类方法。

要记住的最重要的细节是,在类定义中使用它们时。这些方法在代码评估时运行,而不是在运行时运行。

class Base
  def foo_instance
    p "foo instance"
  end

  def self.foo_class
    p "foo class"
  end
end

class Der < Base
  foo_class
  def bar
    p "bar"
  end
end

Der.new.bar

将产生

"foo class"
"bar"

答案 1 :(得分:1)

要创建类方法,您可以执行以下任一操作。

class Base
  def self.foo
  end
end

class Base
  class << self
    def foo
    end
  end
end

因为它们是类方法,所以你可以在类

上调用它们

Base.foo

答案 2 :(得分:1)

所以你所说的是“类方法” - 类方法是在类本身上定义的方法,而不是在类的实例上定义的方法。请注意以下事项:

class Greeter
  def initialize(name)
    @name = name
  end

  def greet
    "hello, #{@name}"
  end
end

Greeter.new("bob").greet # => "hello, bob"

#greetGreeter类的实例方法。但是,.new是一个“类方法” - 这是一个在类本身上调用的方法。尝试在.greet课程上致电Greeter会产生NameError

Greeter.greet # ! NameError

因此,如果要定义这样的“类方法”,则必须使用以下语法之一:

class Greeter
  def self.greet(name)
    "hello, #{name}"
  end

  class << self
    def greet(name)
      "hello, #{name}"
    end
  end

  class << Greeter
    # same as above
  end
end

def Greeter.greet(name)
  "hello, #{name}"
end

回到原来的问题,如果你重新打开迎宾班,现在可以使用.greet方法:

class Greeter
  greet "bob" # => "hello, bob"
end

这也适用于子类化:

class Host < Greeter
  greet "bob" # => "hello, bob"
end

这就是Rails提供这些方法的方法 - 它们在基类上定义类方法,通常是ActiveRecord::Base,然后你可以使用它 - 解释诸如protect_from_forgery之类的方法。

答案 3 :(得分:1)

protect_from_forgery是一个类方法:可能看起来像这样

 def protect_from_forgery(options = {})
        self.forgery_protection_strategy = protection_method_class(options[:with] || :null_session)
        self.request_forgery_protection_token ||= :authenticity_token
        prepend_before_action :verify_authenticity_token, options
        append_after_action :verify_same_origin_request
      end

所以它由应用程序控制器继承:

class ApplicationController < ActionController::Base

您的示例可以这样写:

class Base
  class << self
    def foo
      @name = "foo"
    end
  end
end

class Der < Base
  foo     #class method from Base
  def bar
    @dummy = "bar"
  end
end

查看foo的值

Der.foo.inspect

答案 4 :(得分:-2)

它的继承。在您的子课程中,您可以使用parrent课程中的所有方法。 首先,您可以在类实例上调用方法。 在你的例子中,你可以这样做:

    base_object = Base.new
    base_object.foo

    der_object = Der.new
    der_object.bar

但也要感谢继承,你可以这样做:

    der_object.foo

以下是使用示例的ruby继承的简单教程: http://rubylearning.com/satishtalim/ruby_inheritance.html

快乐的编码!