Вызов метода из класса Ruby? (или это магия рельсов) - PullRequest
2 голосов
/ 18 января 2010

Я новичок в Ruby и работаю над некоторыми уроками / скринкастами. Я дошел до раздела, где обсуждается обратный вызов before_filter, и он использует какой-то синтаксис, что немного странно для меня. Я не знаю, является ли это особенностью рубина, если это какая-то магия рельсов, и надеялся, что кто-то здесь может установить меня прямо или указать мне правильное направление без руководства

Это фрагмент кода из фильма, который я смотрю

class MachinesController < ApplicationController
    #...
    before_filter :login_required, :only => [:report]
    #...    
    def index
        #etc...
    end

    def login_required
        #etc...
    end
end

В контексте рельсов я понимаю, что before_filter - это обратный вызов, который вызовет login_required метод, когда вызывается действие report. Тем не менее, мне не ясно, что это в контексте рубина. В других языках классы обычно содержат методы, свойства, переменные класса и константы, определенные в фигурных скобках.

Однако это похоже на вызов функции внутри класса, и некоторые эксперименты показали, что вы можете поместить код в определения класса и вызывать его при запуске программы. Это правильно? Если да, существуют ли специальные контекстные правила для кода, который встроен в подобный класс? (т.е. будет ли функция before_filter в rails знать, из какого класса она была вызвана) Если нет, то какая магия здесь используется rails?

Ответы [ 4 ]

5 голосов
/ 18 января 2010

before_filter на самом деле не является обратным вызовом. Это метод класса ActiveRecord::Base, который устанавливает обратный вызов при вызове. Итак, в этом примере:

before_filter :login_required, :only => [:report]

Когда класс загружается, вызывается метод, и он добавляет :login_required в цепочку фильтров для метода report.

Соглашение для вызовов такого типа заключается в отбрасывании паренов, но это будет работать просто отлично (и будет легче определить как вызов метода), если вы сделаете это:

before_filter(:login_required, :only => [:report])
1 голос
/ 23 мая 2012

В отличие от некоторых других языков, в Ruby класс может быть изменен во время выполнения, и вы можете выполнять вызовы функций из определения класса. Так что в данном случае происходит то, что вы вызываете функцию before_filter, которая затем изменяет определение класса MachinesController во время выполнения.

Это механизм, который учитывает поразительно красивый (по крайней мере, на мой взгляд) синтаксис, который вы получаете с Rails, когда кажется, что вы используете какой-то предметно-ориентированный язык для описания своих моделей. Такие вещи, как вызовы функций validates, has_many и belongs_to на классах моделей.

Насколько я понимаю, это называется макросом и подпадает под метапрограммирование. Вы можете узнать больше об этой теме .

0 голосов
/ 18 января 2010

Я точно не знаю, какой у вас вопрос, но вот моя интерпретация:

before_filter

Это вызов метода класса, см. ActionController

:login_required

Это параметр метода before_filter, используемый в качестве обратного вызова с использованием Object # send

:only => [:report]

Это дополнительный параметр хеша для before_filter, см. ActionController снова.

Я бы также посоветовал взглянуть на реализацию метода before_filter для понимания.

0 голосов
/ 18 января 2010

Руби это так круто.Вы можете определенно отправлять сообщения из блока класса.Насколько я понимаю, что-то вроде class, кроме очевидного, контролирует идентичность self.Таким образом, вы должны иметь возможность вызывать любой метод класса или включенные модули оттуда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...