我还是Ruby的新手,基本上只是在完成Cooper的书之后编写我的第一个微程序.我被指向避免猴子修补的方向,但问题是我不知道有什么替代方法可以实现相同的行为.基本上,我想添加一个每个字符串对象都可以访问的新方法.明显的猴子修补方式是:
class String
def do_magic
...magic...
end
end
Run Code Online (Sandbox Code Playgroud)
我记得有一种使用String.send的方法.但我不记得它是如何完成的,也不记得我在哪里阅读它.任何人都可以指出任何仍然可以使该方法可用于String类和子对象的替代方法吗?
在Ruby中,程序员可以更改预定义的类.所以一个非常糟糕的程序员可以做类似的事情:
class String
def ==(other)
return true
end
end
Run Code Online (Sandbox Code Playgroud)
显然,几乎没有人会这么愚蠢,但是对于预定义类的更微妙的改变可能会导致已经工作的代码出现问题的想法在我看来违反了封装原则.
四个问题:
我知道这是一个有点主观的问题,但我真的想知道更广泛的编程社区对这个所谓的"猴子修补"的看法.
直到一小时前,我确信在python Foo ().bar ()中只不过是一个简短的手,Foo.bar (Foo () )它将实例作为第一个参数传递.在这个例子中,最后两行(显然)做同样的事情:
class Foo (object):
def bar (self): print "baz"
qux = Foo ()
qux.bar ()
Foo.bar (qux)
Run Code Online (Sandbox Code Playgroud)
但是现在我有一个类Animal,它有一个静态方法populate(),它返回man已知的所有动物的列表.此外,Animal的每个实例都有一个方法populate(),它使用随机值填充实例的属性.
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import random
animals = [ ("Bella", "cow"), ("Spike", "dog"), ("José", "iguana"), ("Tux", "penguin") ]
class Animal (object):
@staticmethod
def populate (*args): return map (lambda x: Animal (*x), animals)
def __init__ (self, name = None, species = None):
def bar (): self.name, self.species = random.choice (animals) …Run Code Online (Sandbox Code Playgroud) 我需要monkeypatch请求的Response类(版本1.0.4,此问题的当前版本),以添加其他方法.
我有这个代码:
import requests
class Response(requests.models.Response):
def hmm(self):
return 'ok'
requests.models.Response = Response
r = requests.get('http://bbc.co.uk')
print r
Run Code Online (Sandbox Code Playgroud)
原始响应调用super()时失败 - https://github.com/kennethreitz/requests/blob/master/requests/models.py#L391
我认为这是因为它变得困惑,因为我已经取代了课程,我觉得我在做一些愚蠢的事情,任何想法?提前致谢.
我想确保datetime.datetime.now()返回一个特定的日期时间用于测试目的,我该怎么做?我试过pytest的monkeypatch
monkeypatch.setattr(datetime.datetime,"now", nowfunc)
Run Code Online (Sandbox Code Playgroud)
但这给了我错误 TypeError: can't set attributes of built-in/extension type 'datetime.datetime'
我明白,如果代码的结构使得它被编程为接口,那么模拟它是微不足道的; 但是,我正在使用一个我无法改变的代码库(这不是我的代码库),事实并非如此.
这个代码库是高度互联的,没有任何东西被编程到接口,只有结构,所以没有依赖注入.
结构本身只包含其他结构,所以我也不能这样做.我不相信我可以对方法做任何事情,并且存在的少数函数不是变量,所以我不知道将它们交换掉.继承在golang中不是一件事,所以这也是不行的.
在像python这样的脚本语言中,我们可以在运行时修改对象,也就是猴子补丁.在golang中我能做些什么吗?试图找出一些方法来测试/基准测试而不触及底层代码.
我使用python,我对测试有点新意.我经常看到测试用本地方法替换外部依赖项,如下所示:
import some_module
def get_file_data():
return "here is the pretend file data"
some_module.get_file_data = get_file_data
# proceed to test
Run Code Online (Sandbox Code Playgroud)
我在这个问题中看到这被称为"猴子修补" .我还看到"模拟"这个词与"钱修补"或者似乎非常相似的场景一起使用了很多.
这两个概念有什么区别吗?
因此,我决定向urlActiveStorage :: Attachment对象添加attr_accessor。
在开发中,该补丁会保留一段时间,直到看起来“已丢失”为止。这意味着它可以工作几分钟,然后不再工作。然后,我需要重新启动服务器才能再次应用补丁。我认为我没有正确打补丁,因此我需要在该方面提供建议。
这是我尝试过的:
lib / ext / active_storage / attachment.rb
第一次尝试 :
module ActiveStorageUrl
extend ActiveSupport::Concern
included do
attr_accessor :url
end
end
ActiveStorage::Attachment.send :include, ActiveStorageUrl
Run Code Online (Sandbox Code Playgroud)
第二次尝试
class ActiveStorage::Attachment < ActiveRecord::Base
attr_accessor :url
end
Run Code Online (Sandbox Code Playgroud)
顺便提一下,在这两种情况下,它都装有:
config / initializers / monkey_patches.rb
require 'ext/active_storage/attachment'
Run Code Online (Sandbox Code Playgroud)
So when it work I have no error message, but after a while the patch "diseapear" (lacking better terms), and I get the following error, telling me my attr_accessor is not there anymore. …
ruby monkeypatching ruby-on-rails ruby-on-rails-5 rails-activestorage
是否可以在PowerShell中编写扩展方法?或者在运行时直播现有类型的新方法,如[string] live?
当模块A的函数应该是可导入的时候,如何从模块B中获取补丁模块A,以便我可以使用multiprocessing标准库包运行模块A的函数?
客户端请求了一个不适用于我们任何其他客户端的修补程序,因此我创建了一个新分支,并为它们编写了一个单独的模块,以便从主分支中轻松合并更改.为了保持客户端与预修复程序行为的向后兼容性,我在应用程序中将此修补程序实现为可配置设置.因此,我不想替换旧代码 - 只需在打开设置时对其进行修补即可.我通过猴子修补做到了这一点.
该__main__模块读入配置文件.如果配置打开了修补程序的开关,则通过用模块中定义的代码替换几个函数来__main__修补我engine的hotfix模块 - 实质上,被替换的函数是最大化函数的关键函数.该engine模块稍后会加载一个工作池multiprocessing.
一旦multiprocessing工作人员开始工作,第一件事multiprocessing就是重新导入*engine模块并查找__main__试图替换的关键功能(然后multiprocessing将控制交给我的代码并开始最大化算法).由于engine正在通过一个全新的流程重新导入,并且新流程不会重新运行__main__(配置文件被读取的地方)因为这会导致无限循环,所以它不知道重新进行猴子补丁engine.
如何在代码中保持模块化(即,将修补程序代码保存在单独的模块中)并仍然利用Python的multiprocessing包?
*注意我的代码必须在Windows(对我的客户端)和Unix(为了我的理智......)上工作
monkeypatching ×10
python ×5
ruby ×3
mocking ×2
unit-testing ×2
.net ×1
datetime ×1
go ×1
import ×1
oop ×1
powershell ×1
pytest ×1
python-3.x ×1
static ×1
testing ×1