Как перегрузить операторы с именем метода в Ruby? - PullRequest
0 голосов
/ 05 апреля 2011

Допустим, у меня есть класс с именем Foo:

Class Foo
  def method=(params)
    puts params
  end
  def +(params)
    puts params
  end
  def method+(params)
    puts params
  end
end

В приведенном выше описании, после инициализации класса новым объектом, который я назову myobj (myobj = Foo.new), вызов myobj.method = "string" и myobj + "string" выведет эту строку. Однако при попытке определить метод + возникает синтаксическая ошибка. Я хочу иметь возможность называть myobj.method + "string". Кто-нибудь может помочь?

Ответы [ 3 ]

3 голосов
/ 05 апреля 2011

Это на самом деле не тот случай, когда символы могут появляться в именах методов («+» технически разрешено), а скорее правила синтаксического анализа и приоритета языка.

Причина, по которой работает def method=, заключается в том, что это специальный синтаксис Ruby для методов доступа к свойствам. Когда вы определяете method=, семантически вы говорите, что foo имеет доступную переменную экземпляра @method или, по крайней мере, действует так же.

Это особый случай, и все другие операторы связываются менее сильно, чем вызов метода .. В foo.method + "string", method вызывается для foo, а затем +("string") вызывается для результата.

1 голос
/ 05 апреля 2011

Ruby не позволит вам определить метод whatever+, как это было бы с whatever= - если вам нужно описываемое поведение, вам нужно создать объект "method", определите +оператор для него и вернуть его из вызова Foo.method:

class Method
    def + (params)
        puts params
    end

    def = (params)
        puts params
    end
end

class Foo
    def + (params)
        puts params
    end

    def method
        return Method.new
    end
end

Я также переместил оператор = в объект метода, но это не имеет значения (так какВы можете def method=) - это просто казалось логичным.И если вам нужно применить это на практике, вам, вероятно, следует сделать Method классом-членом Foo:

class Foo
    class Method
    end
end

, чтобы вы сохранили свои пространства имен в чистоте.Вы всегда можете использовать Foo::Method, чтобы попасть в этот класс, когда вам это нужно.

Надеюсь, это поможет!

0 голосов
/ 05 апреля 2011

Метод не является объектом, а операторы являются атрибутами объектов, а не методами.Это не сработает.

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