我试图修补一个Perl类:我想改变现有方法的行为.
perlmonks上的此节点显示如何将函数添加到现有类.我发现这个模式也可以用来为现有函数提供一个新的实现.
但是,我想知道如何调用原始函数.
我正在寻找这样的东西:
use ExistingClass;
# TODO: Somehow rename existingFunction() to oldExistingFunction().
sub ExistingClass::existingFunction {
my $self = shift;
# New behavior goes here.
$self->oldExistingFunction(@_); # Call old behavior.
# More new behavior here.
}
Run Code Online (Sandbox Code Playgroud) 在我开始自己编写之前,有没有人看过以下行为的ruby实现?
puts 7.nextprime(); #=> 11
puts 7.previousprime(); #=> 5
puts 7.isprime(); #=> true
Run Code Online (Sandbox Code Playgroud)
显然,对于大数字来说,这种事情会很难看,但对于从不超过几千的整数(对我来说是常见的例子)来说,合理的实现是可行的,因此这个问题.
如果您的同事"打开"("monkeypatches")Ruby中的一个类并重新定义了您需要使用的一些重要功能,那么如何在不破坏已经依赖于其monkeypatched定义的系统的情况下访问原始的monkeypatched功能?
我知道我可以执行以下操作来向String类添加方法
class String
def do_something
puts self.size
end
end
var = "test"
var.do_something
Run Code Online (Sandbox Code Playgroud)
这将回来 4
我希望能够有一个带有函数的模块,该函数接受一个String,但是能够do_something在这个字符串上调用该方法(例如见下文) - 它可能吗?
编辑:添加了无效的示例代码
module TestModule
class String
def do_something
puts self.size
end
end
def self.test(str)
str.do_something
end
end
Run Code Online (Sandbox Code Playgroud)
这给出了错误: undefined method 'do_something' for "hello":String (NoMethodError)
部分类背后的想法是你可以将某些功能组合在一起.C#中最好的例子是将控件定义放在一个文件中,将事件处理程序放在另一个文件中.在Ruby中,您可以使用Monkey修补来替换整个函数等,以获取代码来执行您想要的操作.
我还没有找到理由这样做,但我认为随着网络的改进,更多的应用程序将在客户端,所以我想知道我在服务器端语言中找到的一些很棒的功能,我也可以在Javascript中使用.
有人知道吗?
在我最近的一系列问题中,我问到了与内部人士的混淆argparse.大多数情况下,我想更改定义为的属性:
class FooClass(object):
def __init__(self):
self._this_is_a_re=re.compile("foo")
Run Code Online (Sandbox Code Playgroud)
由于它是"受保护的",我想在我用自己的正则表达式替换之前检查这个属性是否存在以及它是否是正则表达式.例如:
import re
myFoo=FooClass()
attr='_this_is_a_re'
if(hasattr(myFoo,attr) and isinstance(getattr(myFoo,attr),re.RegexObject):
setattr(myFoo,attr,re.compile("bar"))
Run Code Online (Sandbox Code Playgroud)
这会因属性错误而失败,因为RegexObject即使它在文档中,re也没有命名属性.为什么RegexObject已记录但不可用?我应该在那里使用什么?我想我可以说:type(a) is type(b)但是这看起来很难看......
我想通过提供shuffle和shuffle!方法来monkeypatch Ruby的String类.
class String
def shuffle
self.split('').shuffle.join
end
end
Run Code Online (Sandbox Code Playgroud)
它返回一个新字符串.如何编写shuffle!修改字符串而不是返回副本的方法?
我试图自己搞清楚,但String的源代码是在MRI中的C语言.
我想修补一个单一的类方法,保持旧的功能.考虑一下我的代码来获取想法.这是我的代码(非常合成的例子).
#!/usr/bin/env python
class A:
@classmethod
def foo(kls, param):
print 'A.foo called, param is ' + param
def bar(self, param):
print 'A.bar called, param is ' + param
a = A()
a.foo('param_foo')
a.bar('param_bar')
# Patching things
def bar_wrapper(wrapped_func):
def _w(*args, **kwargs):
print '<bar_wrap>'
wrapped_func(*args, **kwargs)
print '</bar_wrap>'
return _w
def foo_wrapper(wrapped_func):
# Something missing here?
def _w(*args, **kwargs):
print '<foo_wrap>'
wrapped_func(*args, **kwargs)
print '</foo_wrap>'
return _w
# Everything is pretty ok
A.bar = bar_wrapper(A.bar)
a.bar('is_is_wrapped?')
# Failed to wrap @classmethod …Run Code Online (Sandbox Code Playgroud) python monkeypatching decorator class-method python-decorators
我目前正在编写一个与竹构建服务器交互的小库。测试是使用 pytest 完成的。我陷入了以下问题。我想测试一个运行直到满足某些状态的 while 循环。阅读 pytest 文档,我试图“模拟”/monkeypatch 状态,但它并没有真正起作用。我可能在这里做错了一些基本的错误:这是有问题的 while 循环:
# determine current status
running = self._is_a_build_running()
# turn on and off running powerplug while building
while running:
self.feedback.turn_off_success()
self.feedback.turn_on_running()
time.sleep(self.blinker_time)
self.feedback.turn_off_running()
self._update_builds_status()
running = self._is_a_build_running()
Run Code Online (Sandbox Code Playgroud)
所以我用 pytest 尝试的是为正面和负面创建一个固定装置,_is_a_build_running如下所示:
@pytest.fixture(scope='function')
def mock_is_a_build_running():
return False
Run Code Online (Sandbox Code Playgroud)
然后使用 ThreadPool 使用此测试方法(此处解释了如何从 python 中的线程获取返回值?),因为我还需要包含 while 循环的方法的结果。
def test_update_status_running(bamboopickups, monkeypatch,
mock_update_overall_data_positive,
mock_update_builds_status_positive,
mock_is_a_build_running):
monkeypatch.setattr('BambooPickup._update_overall_data', lambda x: mock_update_overall_data_positive)
monkeypatch.setattr('BambooPickup._update_builds_status', lambda x: mock_update_builds_status_positive)
pool = ThreadPool(processes=1)
async_result = pool.apply_async(bamboopickups.update_status())
monkeypatch.setattr('BambooPickup._update_overall_data', lambda x: mock_update_overall_data_positive)
monkeypatch.setattr('BambooPickup._is_a_build_running', …Run Code Online (Sandbox Code Playgroud) 给定一个带有类Foo的模块,该模块具有调用bar模块范围中定义的函数的方法,是否有办法在bar不修改模块的情况下替换不同的函数?
class Foo(object):
def run(self):
bar()
def bar():
return True
Run Code Online (Sandbox Code Playgroud)
那么我的一个实例Foo为,我想替代的功能baz()为bar(),而无需修改Foo类.
monkeypatching ×10
python ×4
ruby ×4
class-method ×1
decorator ×1
javascript ×1
math ×1
mocking ×1
perl ×1
primes ×1
pytest ×1
regex ×1
reverse ×1
ruby-1.9.2 ×1
unit-testing ×1