有一个包含许多方法的类,所有方法都返回string(url)。我想添加一个在前面任何方法之后调用的新方法,该方法向url添加了额外的参数。例如:
Class.method.my_method
返回
www.domain.com/xxx/xxx?my_method_return
最好的方法是什么?
另外,有什么资料可以找到类似问题的解决方案吗?我不确定是否可以在其他地方找到答案。
答案 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