Как добавить метод, вызванный после другого метода в Ruby - PullRequest
0 голосов
/ 13 октября 2018

Существует класс, который имеет много методов, все возвращающие строку (url).Я хочу добавить новый метод, вызванный после любого из предыдущих, который добавляет дополнительный параметр в URL.Примером может быть:
Class.method.my_method
return
www.domain.com/xxx/xxx?my_method_return
Каков наилучший способ сделать это?

Также есть ли источник, где я мог бы найти решения для подобных проблем?Я разместил это здесь, так как я не уверен, где еще я мог бы найти ответ.

Ответы [ 3 ]

0 голосов
/ 13 октября 2018

Ваша запись Class.method обозначает метод класса.Но ваше описание звучит как стандартный метод Class#method.Для пояснения, последний эквивалентен Class.new.method.Здесь я предполагаю, что ваш вопрос связан с последним.

Я думаю, что стандартной стратегией является использование переменной экземпляра, которая содержит информацию о обработанном до сих пор URL-адресе.Вот пример.

class MyClass
  attr_reader :url  # defines the reading method "url"
  def initialize(baseurl)
    @url = baseurl
  end

  def my_method1
    @url << "?" + "my_method1_return"
  end

  def my_method2
    @url << "?" + "my_method2_return"
  end
end

my_url   = MyClass.new('www.domain.com/xxx/xxx')
string_url0 = my_url.url         # => 'www.domain.com/xxx/xxx'
string_url1 = my_url.my_method1  # => 'www.domain.com/xxx/xxx?my_method1_return'
string_url2 = my_url.my_method2  # => 'www.domain.com/xxx/xxx?my_method1_return?my_method2_return'
my_url.url        # == string_url2 == 'www.domain.com/xxx/xxx?my_method1_return?my_method2_return'

Что касается общего источника информации, я думаю, что проблема связана с фундаментальным шаблоном проектирования ООП, как правильно отмечено.Итак, я не могу придумать ни одного ярлыка, но программист учится годами, изучая его с помощью учебников, реального программирования и т. Д ...

0 голосов
/ 13 октября 2018

Вы можете добавить оператор yield в конец вашего метода, а затем передать блок для добавления дополнительного параметра в URL.

Например,

class MyClass
  def my_method url
    # do some operation on url
    yield url
  end
end

Затем вы можете использовать егокак следует:

m = MyClass.new
m.my_method("url") do |url|
  # do some operation on url
end
0 голосов
/ 13 октября 2018

Одним из возможных решений будет динамическое создание модуля и Module#prepend для исходного класса.Допустим, у нас есть этот класс:

class Origin
  def m1; "foo"; end
  def m2; "bar"; end  
end 

Origin.instance_methods(false)
#=> [
#  [0] m1() Origin (unbound)
#  [1] m2() Origin (unbound)
# ]

Давайте определим наш модуль, пройдя через методы исходного класса (или мы можем альтернативно передать список методов, которые мы хотим перезаписать):

Appender = Module.new do
  # might be just %i[m1 m2].each do |m|  
  Origin.instance_methods(false).each do |m|  
    define_method m do |*args|    
      super(*args) + "?answer=42"      
    end  
  end  
end  

Теперь давайте добавим его к исходному классу:

Origin.prepend Appender

И вуаля:

Origin.new.m1
#⇒ "foo?answer=42"
Origin.new.m2
#⇒ "bar?answer=42"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...