如何在Ruby中添加在另一个方法之后调用的方法

时间:2018-10-13 13:37:06

标签: ruby oop design-patterns

有一个包含许多方法的类,所有方法都返回string(url)。我想添加一个在前面任何方法之后调用的新方法,该方法向url添加了额外的参数。例如:
 Class.method.my_method
返回
www.domain.com/xxx/xxx?my_method_return
    最好的方法是什么?

另外,有什么资料可以找到类似问题的解决方案吗?我不确定是否可以在其他地方找到答案。

3 个答案:

答案 0 :(得分:2)

您的符号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'

至于一般的信息来源,我认为这个问题与OOP的基本设计模式有关,正确地加以标记。 因此,我想不出任何捷径,但是程序员多年来通过学习教科书,实际编程等来学习它。

答案 1 :(得分:1)

可能的解决方案之一是动态创建一个模块,并将其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"

答案 2 :(得分:1)

您可以在方法的末尾添加num_insects语句,然后传递一个块以向URL添加额外的参数。

例如

num_insects = 8 # Must be >= 1

while num_insects <= 100:
    print(num_insects)
    num_insects *= 2  

然后您可以按以下方式使用它:

yield