在类体中声明的Ruby方法调用
我刚刚开始学习Ruby的ruby,我遇到如下代码:
class Post < ActiveRecord::Base validates_presence_of :title belongs_to :user end
在类体内有两个方法调用。 我很难find任何ruby文档,这些文档描述了如何从一个类的主体(但不包括任何方法)调用方法调用。 我所有的书籍,只描述如何定义类和实例方法,以及如何从其他方法中调用它们。
我所拥有的问题是:这些方法如何以及何时被调用? 他们如何定义? 他们是在一些活跃的logging模块中定义的混合?
类定义的主体就像任何其他的代码一样是一个执行上下文。 代码在类的上下文中执行(意思是self
是类对象,它是Class的一个实例)。 您可以拥有局部variables和实例variables(这些variables将属于类对象本身而不是类的实例),您可以调用类对象响应的任何方法。 代码在类定义块完成后运行。
在这种情况下,ActiveRecord :: Base定义了类方法validates_presence_of
和belongs_to
。
Yehuda Katz在他的博客上对此有一个很好的解释。 见第四点: class主任不是特别的 。
这些是类方法或“单例”方法。 你应该熟悉的是attr_accessor。 我们可以在testing类中实现类似的东西。
class Klass def self.add_getter_and_setter(symbol) module_eval "def #{symbol}; @#{symbol}; end" module_eval "def #{symbol}=(val); @#{symbol} = val; end" end end class Person < Klass add_getter_and_setter :name add_getter_and_setter :phone end person = Person.new person.name = 'John Smith' person.phone = '555-2344' person # returns <Person:0x28744 @name="John Smith", @phone="555-2344">
在上面的例子中,我们用“def self.add_getter_and_setter”创build了类方法,但这不是唯一的方法。
class Klass class << self # opens the singleton class def add_getter_and_setter(symbol) # note we dont specify self as it is already within the context of the singleton class .. end end end
使用扩展。 Module#extend是一个用类方法扩展类的方法,同样,Module#include方法也包含一个带有实例方法的类。
class Klass extend(Module.new do def add_getter_and_setter(symbol) .. end end) end
如果Klass已经被定义,我们可以重新打开它来添加类方法
class Klass end def Klass.add_getter_and_setter(symbol) .. end # or class << Klass def add_getter_and_setter(symbol) .. end end
那么这些是我知道如何做到这一点的一些方法,所以如果你看到不同的语法只是意识到它做的一切。
注意:在rails中,我们使用的通用类方法是“find”。 它直接在Model类中运行。
person = Person.find(1) # finds a person with id:1
回复:这些方法如何以及何时被调用?
[他们在课程被加载时被调用。 您可以在其中一个方法中放置一个断点,并将其视为您的rails项目启动的一部分。]
他们如何定义?
[他们是一stream的方法。 由于这是ruby,可以通过多种方式来定义。]
他们是在一些活跃的logging模块中定义的混合?
[在这种情况下,
validates_presence_of在vendor / rails / activerecord / lib / active_record / validations.rb中定义
belongs_to在vendor / rails / activerecord / lib / active_record / associations.rb中定义
ActiveRecord是一个很大的系统,包含了很多mixin,modules等
请注意,要查看方法的定义位置,我使用http://www.gotapi.com/rubyrails为每个方法,请参阅定义底部的“显示源”链接。;
]
你所看到的是ActiveRecord对象的类级方法。 为了编写你自己的方法,你可以将它们写成插件,然后通过重新打开类定义将它们包含到ActiveRecord中。 Ruby on Rails指南创build一个插件:
http://guides.rubyonrails.org/plugins.html
涵盖了如何编写这样一个插件/类级别的方法。 它是一个很好的文档,说明如何围绕这些方法的意义以及它们如何与实例进行交互。