标签: metaprogramming

如何让活动绑定知道它是否作为函数调用?

我想要这样的东西:

makeActiveBinding("f", function() {
  called_as_a_function <- ... # <- insert answer here
  if(called_as_a_function) { 
    sqrt
  } else {
    1
  }
}, .GlobalEnv)

# Expected output

f + f
#> 2

f(4) + f
#> 3
Run Code Online (Sandbox Code Playgroud)

f在这里使用,应该适用于任何功能

在上面的例子中f返回1f(4)返回sqrt(4)。在我的实际用例中,naked f(not f()) 将返回一个函数对象,因此 Michal 提出的解决方法不能按原样使用。

+为简单起见,我在这里使用它,但它可能是任何函数或没有函数,包括 NSE 函数,例如quote(),因此,例如quote(f)quote(f())解决方案不应更改它们的输入。

我试图玩,sys.calls()但无法得到任何强大的东西。

也欢迎使用低级代码的答案,谁知道黑魔法可能会有所帮助。

这些不会在顶层调用,所以如果你不能使上述工作但可以让以下工作例如也很好,并且实际上它不会是.GlobalEnv这样,如果你可以让它在另一个环境中工作这也很好。

identity(f + f)
#> 2

identity(f(4) + f)
#> …
Run Code Online (Sandbox Code Playgroud)

r metaprogramming

23
推荐指数
1
解决办法
595
查看次数

D模板:最酷的黑客

你在D编程语言中做过或看过的最酷的有点实用的元编程黑客是什么?有点实际意味着排除例如编译时光线跟踪器.

templates d metaprogramming

22
推荐指数
9
解决办法
2534
查看次数

如何反转ruby的include函数

我将在代码中解释我正在寻找的内容,因为这可能是最简洁的:

module Mixin
  def method
    puts "Foo"
  end
end

class Whatever
  include Mixin
end

w = Whatever.new
w.method
=> "Foo"

# some magic here
w2 = Whatever.new
w.method
=> NoMethodError
Run Code Online (Sandbox Code Playgroud)

我曾尝试使用remove_const取消定义Mixin模块,但这似乎对Whatever没有任何影响.我曾假设#include只是将模块的引用添加到类的方法解析链中 - 但这种行为与此不一致.

任何人都可以告诉我幕后实际做了什么,以及如何扭转这种局面?

ruby metaprogramming class

22
推荐指数
2
解决办法
7494
查看次数

使用模板元编程计算阶乘

我不明白这段代码(来自维基百科)是如何工作的:

template <int N>
struct Factorial 
{
    enum { value = N * Factorial<N - 1>::value };
};

template <>
struct Factorial<0> 
{
    enum { value = 1 };
};

// Factorial<4>::value == 24
// Factorial<0>::value == 1
void foo()
{
    int x = Factorial<4>::value; // == 24
    int y = Factorial<0>::value; // == 1
}
Run Code Online (Sandbox Code Playgroud)
  • 这个奇怪的模板是<int N>什么?
  • 这是第二个奇怪的模板是<>什么?
  • 有什么东西 enum
  • 使用此而不是正常的运行时因子计算有什么好处?
  • 你们多久使用一次这个?我一直在使用C++,但之前从未使用过.我错过了C++的一小部分?

谢谢!

c++ templates metaprogramming

22
推荐指数
2
解决办法
2万
查看次数

C程序可以修改其可执行文件吗?

我手上有点太多时间,开始想知道我是否可以写一个自修改程序.为此,我在C中编写了一个"Hello World",然后使用十六进制编辑器在已编译的可执行文件中查找"Hello World"字符串的位置.是否可以修改此程序以打开自身并覆盖"Hello World"字符串?

char* str = "Hello World\n";

int main(int argc, char* argv) {

  printf(str);

  FILE * file = fopen(argv, "r+");

  fseek(file, 0x1000, SEEK_SET);
  fputs("Goodbyewrld\n", file);      
  fclose(file);    

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这不起作用,我假设有一些东西阻止它打开自己,因为我可以将它分成两个单独的程序(一个"Hello World"和一些修改它),它工作正常.

编辑:我的理解是,当程序运行时,它被完全加载到ram中.因此,对于所有意图和目的,硬盘驱动器上的可执行文件是一个副本.为什么修改自己会有问题?

有解决方法吗?

谢谢

c metaprogramming self-modifying

22
推荐指数
2
解决办法
9549
查看次数

Ruby - 使用class_eval定义方法

我正在做SaaS Stanford课程,试图完成这项任务的第5部分

我很难掌握这个概念,这就是我试图做的事情:

class Class
  def attr_accessor_with_history(attr_name)
    attr_name = attr_name.to_s
    attr_reader attr_name
    attr_reader attr_name + '_history'
    class_eval %Q'{def #{attr_name}(a);#{attr_name}_history.push(a) ; end;}'
  end
end
Run Code Online (Sandbox Code Playgroud)

我可能会做各种各样的错误,阅读关于元编程的The Book of Ruby章节,我仍然没有得到它,有人能帮我理解这个吗?

ruby metaprogramming class-eval

22
推荐指数
2
解决办法
2万
查看次数

Tim Sweeney在想什么?(这个C++解析器是如何工作的?)

Epic MegaGames的Tim Sweeney是Unreal的首席开发人员和编程语言极客.许多年前发布了以下屏幕截图到VoodooExtreme:

Tim Sweeney的截图

作为C++程序员和Sweeney粉丝,我被这个迷住了.它显示了通用的C++代码,它实现了某种脚本语言,在这种语言中,语言本身似乎是通用的,因为它可以定义自己的语法.

斯威尼先生从不解释自己.:-)

很少见到这种级别的模板编程,但是当人们想要推动编译器生成优秀的代码或者因为他们想要创建通用代码(例如,现代C++设计)时,你确实会看到它.

Tim似乎正在使用它在Parser.cpp中创建语法 - 您可以看到优先级二元运算符的外观.如果是这种情况,那么为什么Test.ae看起来也在定义语法?

显然这是一个需要解决的难题.胜利用这个代码的工作版本或者最合理的解释来回答,或者如果蒂姆斯威尼发表了答案,他就会自己.:-)

c++ parsing templates metaprogramming

21
推荐指数
2
解决办法
2451
查看次数

可以使用D的模板的示例

我听说D语言具有强大的元编程功能,可以在编译时执行函数.这听起来非常令人兴奋,但我发现很难想到没有它们很难实现的实际例子.

任何人都可以提供一些D的元编程功能非常方便的情况吗?

d metaprogramming

21
推荐指数
4
解决办法
2114
查看次数

静态类型元编程?

我一直在考虑将一些Python代码移植到静态类型语言(例如F#或Scala)时我会想念的内容.库可以替换,简洁可比,但我有很多python代码,如下所示:

@specialclass
class Thing(object):
    @specialFunc
    def method1(arg1, arg2):
        ...
    @specialFunc
    def method2(arg3, arg4, arg5):
        ...
Run Code Online (Sandbox Code Playgroud)

装饰器做了大量工作:用可调用对象替换方法与状态,用额外的数据和属性扩充类等等.虽然Python允许动态猴子补丁元编程任何地方,任何人,任何人,我发现基本上所有我的元编程是在程序的一个单独的"阶段"完成的.即:

load/compile .py files
transform using decorators
// maybe transform a few more times using decorators
execute code // no more transformations!
Run Code Online (Sandbox Code Playgroud)

这些阶段基本上完全不同; 我不在装饰器中运行任何应用程序级代码,也不在主应用程序代码中执行任何ninja replace-class-with-other-class或replace-function-with-other-function.虽然语言的"动态"说我可以在任何我想要的地方这样做,但我从不在主应用程序代码中替换函数或重新定义类,因为它很快就会变得疯狂.

基本上,我在开始运行之前对代码执行单个重新编译.

我在静态类型语言中知道的唯一类似的元编程是反射:即从字符串中获取函数/类,使用参数数组调用方法等.但是,这基本上将静态类型语言转换为动态类型语言,从而失去所有类型的安全性(如我错了请纠正我?).理想情况下,我认为,我会有如下内容:

load/parse application files 
load/compile transformer
transform application files using transformer
compile
execute code
Run Code Online (Sandbox Code Playgroud)

从本质上讲,您将使用使用普通编译器编译的任意代码来扩充编译过程,该代码将对主应用程序代码执行转换.关键是它基本上模拟了"加载,转换,执行"工作流程,同时严格保持类型安全.

如果应用程序代码被borked编译器会抱怨,如果变换器代码被borked编译器会抱怨,如果变换器代码编译但没有做正确的事情,它将崩溃或编译后的步骤将抱怨最终类型不加起来.在任何情况下,您都不会通过使用反射来进行动态调度来获得运行时类型错误:它将在每一步都进行静态检查.

所以我的问题是,这可能吗?它是否已经在我不知道的某种语言或框架中完成了?这在理论上是不可能的吗?我对编译器或形式语言理论不太熟悉,我知道它会使编译步骤完整并且不保证终止,但在我看来,这就是我需要匹配的那种方便的代码 - 转换我在保持静态类型检查的同时使用动态语言.

编辑:一个示例用例将是一个完全通用的缓存装饰器.在python中它将是:

cacheDict = {}
def cache(func):
    @functools.wraps(func)
    def wrapped(*args, **kwargs):
        cachekey = hash((args, kwargs))
        if cachekey not in cacheDict.keys():
            cacheDict[cachekey] …
Run Code Online (Sandbox Code Playgroud)

python f# scala metaprogramming

21
推荐指数
3
解决办法
1266
查看次数

覆盖实例上的特殊方法

我希望有人可以回答这个对Python有深刻理解的:)

请考虑以下代码:

>>> class A(object):
...     pass
...
>>> def __repr__(self):
...     return "A"
...
>>> from types import MethodType
>>> a = A()
>>> a
<__main__.A object at 0x00AC6990>
>>> repr(a)
'<__main__.A object at 0x00AC6990>'
>>> setattr(a, "__repr__", MethodType(__repr__, a, a.__class__))
>>> a
<__main__.A object at 0x00AC6990>
>>> repr(a)
'<__main__.A object at 0x00AC6990>'
>>>
Run Code Online (Sandbox Code Playgroud)

注意repr(a)如何不产生"A"的预期结果?我想知道为什么会这样,如果有办法实现这个目标......

我对比一下,下面的例子可行(也许是因为我们没有尝试覆盖特殊方法?):

>>> class A(object):
...     def foo(self):
...             return "foo"
...
>>> def bar(self):
...     return "bar"
...
>>> from types import …
Run Code Online (Sandbox Code Playgroud)

python metaprogramming

21
推荐指数
2
解决办法
6259
查看次数

标签 统计

metaprogramming ×10

templates ×3

c++ ×2

d ×2

python ×2

ruby ×2

c ×1

class ×1

class-eval ×1

f# ×1

parsing ×1

r ×1

scala ×1

self-modifying ×1