Чтобы использовать себя. или нет.. в Rails
Я уже некоторое время кодирую в Ruby, но я не понимаю, когда использовать:
def self.METHOD_NAME
end
или так:
def METHOD_NAME
end
в любой модели рельсов. Является ли" self " модификатором, как private в Java? Когда я должен использовать его, а когда нет?. Большое спасибо.
6 ответов:
def self.method_name end
определяет метод класса.
def method_name end
определяет метод экземпляра.
этой очень хороший пост на нем.
краткое объяснение того, что это значит:
в ruby вы можете определить методы для конкретного объекта:
a = "hello" def a.informal "hi" end a.informal => "hi"
что происходит, когда вы делаете это то, что объект a, который имеет класс
String
, получает свой класс изменен на "призрак" класс, он же метакласс, одноэлементный класс или eigenclass. Это новый суперкласс классаString
.кроме того, внутри определения класса,
self
устанавливается в определяемый класс, поэтомуclass Greeting def self.say_hello "Hello" end #is the same as: def Greeting.informal "hi" end end
что происходит есть что объект
Greeting
, который имеет классClass
, получает новый метакласс с новыми методами, поэтому при вызовеGreeting.informal => "hi"
в ruby нет такой вещи, как методы класса, но семантика похожа.
хорошее руководство о том, когда использовать, какой:
- если метод зависит от какого-либо внутреннего состояния объекта или должен знать, к какому экземпляру объекта он обращается, то не делайте его классом (
self.
) метод.- если метод не зависит от состояния объекта, или от наличия конкретного экземпляра объекта, то в может быть сделан метод класса.
при создании метода класса, тщательно подумайте о том, какой класс или модуль это принадлежит ему. Если вы когда-нибудь поймаете себя на дублировании кода в методах класса между классами, разложите его на модуль, который могут смешивать другие классы.
в этом контексте - def self.method_name делает его своего рода эквивалентом статического метода Java:
ruby:
class HexHelper def self.to_h(num) sprintf("%x", num) end end use: HexHelper.to_h(12345)
java:
public class HexHelper { public static String toHex(int num) { return new PrintfFormat("%x").sprintf(num); } } use: HexHelper.toHex(12345)