Рассмотрим следующий класс:
class Foo
def an_inst_method
'instance method'
end
def self.a_class_method
'class method'
end
alias_method :a_new_inst_method, :an_inst_method
end
Это не проблема, и вы можете позвонить Foo.new.a_new_inst_method
без проблем.
Я хотел бы иметь возможность иметь метод класса наподобие Foo.add_widget(*items)
псевдонима, чтобы я мог сделать что-то вроде:
Foo.add_widget 'item1'
Foo.add_widgets 'item2', 'item3'
По сути, он похож на «стиль ruby», 1.minute
и 2.minutes
поэтому я хочу создать псевдоним Foo.add_widget
так называемых Foo.add_widgets
вызовов точно такого же метода. Я знаю, что мог бы обернуть это, но я чувствую, что должен быть в состоянии сделать это более чистым способом.
Рассмотрим мою попытку попробовать что-то вроде этого:
class Foo
def an_inst_method
'instance method'
end
def self.a_class_method
'class method'
end
alias_method :a_new_inst_method, :an_inst_method
alias_method :a_new_class_method, :a_class_method
end
Однако я получаю следующую ошибку:
NameError (undefined method `a_class_method' for class `Foo')
И, похоже, это не работает для методов класса. Как мне это сделать?
ruby
alias-method
aarona
источник
источник
Ответы:
alias_method
псевдонимы метода экземпляров получателя. Методы класса на самом деле являются методами экземпляра, определенными в одноэлементном классе класса.Чтобы создать псевдоним метода экземпляра, определенного в одноэлементном классе, вы можете открыть его, используя
class << object
синтаксис.Или вы можете обратиться к нему напрямую, используя
singleton_class
метод.Если вы все еще находитесь в контексте класса,
self
будет ссылаться на класс. Таким образом, вышесказанное также может быть записано как:Или
Или комбинация двух.
источник
Вы можете обернуть методы класса и их
alias_method
вызовы в отдельный модуль и включить этот модуль в свой класс с помощьюextend
:источник
extend ClassMethods
решении. +1Важно понимать, что в Ruby не существует метода класса .
Метод класса на самом деле просто одноэлементный метод. В методах класса нет ничего особенного. Каждый объект может иметь одноэлементные методы. Мы просто называем их «методами класса», когда объект является «
Class
потому что» метод синглтона экземпляраClass
«слишком длинный и громоздкий.Подождите! Я сказал "метод синглтона"?
Еще одна важная вещь, которую нужно понять, это то, что в Ruby не существует такого метода, как синглтон .
Одноэлементный метод - это на самом деле просто обычный скучный старый метод экземпляра одноэлементного класса. В одноэлементных методах нет ничего особенного. Они просто методы экземпляра, как и любой другой метод экземпляра.
На самом деле, в Ruby есть только методы экземпляра. Нет функций, нет конструкторов, нет статических методов, нет методов класса, нет функций модуля, нет одноэлементных методов.
Вопрос не в том, «это метод класса, метод одиночный», а в том, «в каком модуле определен этот метод?».
«Методы Singleton» - это действительно методы экземпляра, определенные в классе Singleton. Синтаксис для доступа к одноэлементному классу
foo
:Существует также метод,
Object#singleton_class
который возвращает одноэлементный класс объекта.Почему я так настойчиво говорю о том, что каждый метод является методом экземпляра, а методы класса не существуют? Потому что это означает, что объектная модель Ruby намного проще, чем думают люди! В конце концов, в своем вопросе вы уже показали, что знаете, как псевдонимы методов экземпляра, но вы говорите, что не знаете, как псевдонимы методов класса. Но это неправильно! Вы делаете знаете , как методы класса псевдоним, потому что они просто методы экземпляра . Если бы вас правильно учили этому факту, вам никогда бы не пришлось задавать этот вопрос!
Как только вы поймете, что каждый метод является методом экземпляра и что то, что мы называем «одноэлементными методами», является просто методами экземпляра одноэлементного класса, решение становится ясным:
Примечание: когда я писал выше, что «нет такой вещи, как X», я имел в виду, что « в языке Ruby нет такой вещи, как X ». Это не означает, что эти понятия не существуют в сообществе Ruby .
Мы регулярно говорим о «одноэлементных методах» и «методах класса» просто потому, что это проще, чем говорить о «методах экземпляра класса singleton» или «методах экземпляра класса singleton объекта, который является экземпляром
Class
класса ». Есть даже такие методы , какObject#define_singleton_method
,Object#singleton_method
,Object#singleton_methods
,Module#private_class_method
,Module#public_class_method
, иModule#module_function
в основной библиотеке Ruby. Но всегда важно помнить, что это не языковые понятия. Это концепции сообщества, которые существуют только в наших головах и в названиях некоторых библиотечных методов.источник
ОК, похоже, я могу сделать что-то вроде этого, и это будет работать:
Если у кого-нибудь есть какая-либо полезная информация о языке Ruby здесь и вы хотели бы представить исчерпывающий ответ, я дам вам +1.
источник
class << self
за ним,alias_method :a_new_class_method, :a_class_method
вы фактически призываетеalias_method
синглтон-классFoo
. Другой способ написать это:singleton_class.alias_method :a_new_class_method, :a_class_method
в контексте класса.alias_method
работает с экземпляром, поэтому вам нужно пойти на один уровень глубже и оперироватьClass
экземпляром или метаклассом класса . У Ruby есть дикая объектная модель, которая может привести к поломке мозга, но она также дает вам массу силы:источник