任何“主要”框架都使用猴子修补/开放类

时间:2022-07-13 11:32:47

I am curious about the usage of the feature known as open classes or monkey-patching in languages like e.g. Ruby, Python, Groovy etc. This feature allows you to make modifications (like adding or replacing methods) to existing classes or objects at runtime.

我很好奇使用称为开放类或猴子修补的功能,例如, Ruby,Python,Groovy等。此功能允许您在运行时对现有类或对象进行修改(如添加或替换方法)。

Does anyone know if major frameworks (such as Rails/Grails/Zope) make (extensive) use of this opportunity in order to provide services to the developer? If so, please provide examples.

有谁知道主要框架(如Rails / Grails / Zope)是否(广泛地)利用这个机会来为开发者提供服务?如果是,请提供示例。

3 个解决方案

#1


Rails does this to a (IMHO) ridiculous extent.

Rails做到了(恕我直言)荒谬的程度。

#2


.Net allows it via extension methods.

.Net允许通过扩展方法。

Linq, specifically, relies heavily on extension methods monkey-patched onto the IEnumerable interface.

具体而言,Linq在很大程度上依赖于猴子修补到IEnumerable接口的扩展方法。

#3


An example of its use on the Java platform (since you mentioned Groovy) is load-time weaving with something like AspectJ and JVM instrumentation. In this particular case, however, you have the option of using compile-time weaving instead. Interestingly, one of my recent SO questions was related to problems with using this load-time weaving, with some recommending compile-time as the only reliable option.

它在Java平台上的使用示例(因为您提到了Groovy)是使用AspectJ和JVM工具之类的加载时编织。但是,在这种特殊情况下,您可以选择使用编译时编织。有趣的是,我最近的一个问题是与使用这种加载时编织的问题有关,有些人建议将编译时作为唯一可靠的选择。

An example of AspectJ using load-time (run-time) weaving to provide a helpful service to the developer can be Spring's @Configuration annotation which allows you to use Dependency Injection on object not instantiated by Spring's BeanFactory.

使用加载时(运行时)编织为开发人员提供有用服务的AspectJ示例可以是Spring的@Configuration注释,它允许您对未通过Spring的BeanFactory实例化的对象使用依赖注入。

You specifically mentioned modifying the method (or how it works), and an example of that being used is an aspect which intercepts am http request before being sent to the handler (either some Controller method or doPost, etc) and checking to see if the user is authorized to access that resource. Your aspect could then decide to return – prematurely – a response with a redirect to login. While not modifying the contents of the method per se, you are still modifying the way the method works my changing the return value it would otherwise give.

您特别提到了修改方法(或它的工作原理),并且使用的一个示例是在发送到处理程序(某些Controller方法或doPost等)之前截取http请求并检查是否用户有权访问该资源。然后,您的方面可以决定 - 过早地 - 返回具有重定向登录的响应。虽然不修改方法本身的内容,但您仍然在修改方法的工作方式,我更改它原本会给出的返回值。

#1


Rails does this to a (IMHO) ridiculous extent.

Rails做到了(恕我直言)荒谬的程度。

#2


.Net allows it via extension methods.

.Net允许通过扩展方法。

Linq, specifically, relies heavily on extension methods monkey-patched onto the IEnumerable interface.

具体而言,Linq在很大程度上依赖于猴子修补到IEnumerable接口的扩展方法。

#3


An example of its use on the Java platform (since you mentioned Groovy) is load-time weaving with something like AspectJ and JVM instrumentation. In this particular case, however, you have the option of using compile-time weaving instead. Interestingly, one of my recent SO questions was related to problems with using this load-time weaving, with some recommending compile-time as the only reliable option.

它在Java平台上的使用示例(因为您提到了Groovy)是使用AspectJ和JVM工具之类的加载时编织。但是,在这种特殊情况下,您可以选择使用编译时编织。有趣的是,我最近的一个问题是与使用这种加载时编织的问题有关,有些人建议将编译时作为唯一可靠的选择。

An example of AspectJ using load-time (run-time) weaving to provide a helpful service to the developer can be Spring's @Configuration annotation which allows you to use Dependency Injection on object not instantiated by Spring's BeanFactory.

使用加载时(运行时)编织为开发人员提供有用服务的AspectJ示例可以是Spring的@Configuration注释,它允许您对未通过Spring的BeanFactory实例化的对象使用依赖注入。

You specifically mentioned modifying the method (or how it works), and an example of that being used is an aspect which intercepts am http request before being sent to the handler (either some Controller method or doPost, etc) and checking to see if the user is authorized to access that resource. Your aspect could then decide to return – prematurely – a response with a redirect to login. While not modifying the contents of the method per se, you are still modifying the way the method works my changing the return value it would otherwise give.

您特别提到了修改方法(或它的工作原理),并且使用的一个示例是在发送到处理程序(某些Controller方法或doPost等)之前截取http请求并检查是否用户有权访问该资源。然后,您的方面可以决定 - 过早地 - 返回具有重定向登录的响应。虽然不修改方法本身的内容,但您仍然在修改方法的工作方式,我更改它原本会给出的返回值。