С ударом> = 3 следующие работы:
$ ./s
0 is: ./s
BASH_SOURCE is: ./s
$ . ./s
0 is: bash
BASH_SOURCE is: ./s
$ cat s
#!/bin/bash
printf '$0 is: %s\n$BASH_SOURCE is: %s\n' "$0" "$BASH_SOURCE"
Тело определения класса - это контекст выполнения для кода, как и любого другого. Код там выполняется в контексте класса (то есть self
- это объект класса, который является экземпляром класса). У вас могут быть локальные переменные и переменные экземпляра (которые будут принадлежать самому объекту класса, а не экземплярам класса), и вы можете вызвать любой метод, на который отвечает объект класса. Код запускается после завершения блока определения класса.
В этом случае ActiveRecord ::
Re: How and when are these methods called?
[They're called when the class is loaded. You can put a breakpoint in one of the methods and see that it is called as part of the startup of your rails project.]
How are they defined?
[They're class methods. Since this is ruby, they could be defined in a number of ways.]
Are they mixins defined in some active record module?
[In this case,
validates_presence_of is defined in vendor/rails/activerecord/lib/active_record/validations.rb
belongs_to is defined in vendor/rails/activerecord/lib/active_record/associations.rb
ActiveRecord is a big system, includes many mixins, modules, etc.
Note, to see where the methods are defined, I use http://www.gotapi.com/rubyrails for each method, see the "Show Source" link at the bottom of the definition.
]
У Иегуды Каца есть хорошее объяснение этого в своем блоге. См. Пункт 4: Классовые тела не особенные .
These are class methods or 'singleton' methods. One you should be familiar with is attr_accessor. We can implement something like it in a test class.
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">
In the above example we created the class method with 'def self.add_getter_and_setter' but this is not the only way.
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
Using extend. Module#extend is a method that extends a class with class methods likewise the method Module#include includes a class with instance methods.
class Klass
extend(Module.new do
def add_getter_and_setter(symbol)
..
end
end)
end
If Klass has already been defined we can reopen it to add class methods
class Klass
end
def Klass.add_getter_and_setter(symbol)
..
end
# or
class << Klass
def add_getter_and_setter(symbol)
..
end
end
Well those are a few ways I know how to do this so if you see different syntax just realize its all doing the same thing.
Note: in rails a common class method we all use is 'find'. It is run directly off the Model class.
person = Person.find(1) # finds a person with id:1
What you are seeing are class level methods for an ActiveRecord object. To write your own methods that perform like that you would write them as a plugin and then include them into ActiveRecord by re-opening the class definition. The Ruby on Rails guide to creating a plugin:
http://guides.rubyonrails.org/plugins.html
Covers how one would write such a plugin / class-level methods. Its a good document on how to wrap your head around what those kinds of methods mean and how they interact with instances.