В модуле Ruby, как вы проверяете, существует ли метод в контексте, который использует модуль? - PullRequest
0 голосов
/ 01 июля 2018

Некоторый контекст

Я играю с Руби, чтобы углубить свои знания и повеселиться, одновременно совершенствуя свои знания эсперанто с помощью только что начавшегося игрушечного проекта под названием *ue . По сути, цель состоит в том, чтобы использовать средства Ruby для реализации DSL, который соответствует признакам эсперанто, которые я считаю интересными в контексте языка программирования.

Актуальная проблема

Итак, первая черта, которую я хотел бы реализовать, - это перегиб глаголов, использующий инфинитив в объявлении метода (оканчивающийся на -i), и jussive (оканчивающийся на -u) для вызова метода.

Первая рабочая базовая реализация выглядит так:

module Ĝue
  def method_missing(igo, *args, &block)
    case igo
    when /u$/
      celo = igo.to_s.sub(/u$/, 'i').to_s
      send(celo)
    else
      super
    end
  end
end

И это работает. Теперь следующий шаг - сделать его более устойчивым, поскольку нет гарантии, что celo будет существовать, когда модуль попытается вызвать его. То есть модуль должен реализовывать метод respond_to?. Таким образом, вопрос, как модуль узнает, включает ли контекст, где требуется модуль, соответствующий инфинитивный метод? Даже после добавления extend self в начале модуля, внутри модуля methods.include? :testi по-прежнему возвращается false при тестировании со следующим кодом, хотя вызов testu работает отлично:

#!/usr/bin/env ruby

require './teke/ĝue.rb'
include Ĝue
def testi; puts 'testo!' ;end
testu

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

1 Ответ

0 голосов
/ 01 июля 2018

Нашел рабочее решение через В Ruby как проверить, определен ли метод "foo = ()"?

Так что в этом случае это можно проверить с помощью

eval("defined? #{celo}") == 'method'
...