Programming languages 您可以用什么语言动态地重写函数?
我最近有必要用javascript动态地重写javascript函数。我做这件事的轻松程度和乐趣让我大吃一惊 在这里,我有一些HTML:Programming languages 您可以用什么语言动态地重写函数?,programming-languages,lisp,dynamic-languages,Programming Languages,Lisp,Dynamic Languages,我最近有必要用javascript动态地重写javascript函数。我做这件事的轻松程度和乐趣让我大吃一惊 在这里,我有一些HTML: <div id="excelExport1234" onclick="if(somestuff) location.href='http://server/excelExport.aspx?id=56789&something=else'; else alert('not important');" >Click here
<div id="excelExport1234"
onclick="if(somestuff) location.href='http://server/excelExport.aspx?id=56789&something=else'; else alert('not important');"
>Click here to export to excel</div>
它就像一个冠军!excelExport.onclick返回一个函数对象,我将其转换为字符串,并对其执行一些字符串管理。由于它现在是“function(){…}”的形式,我只需返回并将其分配给dom对象的onclick事件。必须使用eval有点难看,但毕竟没有一个javascript函数构造函数可以接受一个字符串代码并将其很好地转换为对象
无论如何,我的观点不是我超级聪明(我不是),我的观点是这很酷。我知道javascript并不是唯一能做到这一点的语言。我听说lisp多年来一直使用宏来实现这一目的。除了要真正理解宏,你需要真正理解lisp,我不理解它,我只是“有点理解”
因此,我的问题是:您可以(轻松地)用哪些其他语言动态重写函数,您能给我举个简单的例子吗?我想看看您还可以在哪里执行此操作,以及如何执行此操作
(另外,我不知道该怎么称呼它,所以我随机猜测)我在TCL一直都是这么做的,这是一件轻而易举的事,工作得非常出色。我可以通过网络调查somethings接口,然后动态创建一个定制接口来访问和控制内容。例如,您可以从通用SNMP库创建自定义SNMP接口 我没有使用过它,但C#有一些内置的支持来生成自己的字节码,这相当令人印象深刻
我在C语言中也做过类似的事情,但它不可移植,几乎不值得这么麻烦。这是一种有时用于“自我优化”代码的技术,用于生成适当的C函数以优化处理给定的数据集。LISP是目前的最终语言。LISP函数是实际的LISP列表,这意味着您可以像处理任何其他数据结构一样处理LISP源代码 下面是一个非常简单的例子,说明它是如何工作的:
(define hi
(lambda () (display "Hello World\n")))
;; Displays Hello World
(hi)
(set! hi
(lambda () (display "Hola World\n")))
;; Displays Hola World
(hi)
然而,这在函数为一级对象的任何语言中都是可能的。LISP这种语法的强大功能最有趣的展示之一就是它的宏系统。我真的觉得我不能公正地讨论这个话题,所以如果你感兴趣,请阅读以下链接:
用Perl很容易
*some_func = sub($) {
my $arg = shift;
print $arg, "\n";
};
some_func('foo');
关于Sam Saffron的请求:
*hello_world = sub() {
print "oops";
};
hello_world();
*hello_world = sub() {
print "hello world";
};
hello_world();
也称为退化码。这通常被认为是一件坏事,高级语言的目标是防止它被轻松编写
这来自维基百科条目:
一些人认为自修改代码是一种糟糕的做法,这会使代码更难阅读和维护。然而,也有一些自修改被认为是可以接受的方式,例如当子例程指针被动态修改时——即使效果与直接修改几乎相同
我想这取决于你定义的“轻松动态重写”。例如,在.Net中有Func类型和lambdas,它允许您将函数定义为变量或临时匿名函数,例如
int[] numbers = {1, 2, 3, 4, 5};
Func<int[], int> somefunc;
if (someCondition)
{
somefunc = (is => is.Sum());
} else {
somefunc = (is => is.Count());
}
Console.WriteLine(somefunc(numbers).ToString());
int[]数字={1,2,3,4,5};
Func somefunc;
如果(某些条件)
{
somefunc=(is=>is.Sum());
}否则{
somefunc=(is=>is.Count());
}
Console.WriteLine(somefunc(numbers.ToString());
上面是一个非常做作的例子,要么计算整数数组中的项,要么求和,然后根据某些任意条件使用动态创建的函数
注意-请不要指出,没有lambdas,这些事情很容易就能完成(它们显然可以做到)。我只是想写一个非常简单的例子,用C#来演示这个概念。我认为大多数动态语言都是这样。下面是一个Python示例 def f(x): print x def new_function(x): print "hello", x f("world") f = new_function f("world") def f(x): 打印x def新功能(x):打印“hello”,x f(“世界”) f=新的_函数 f(“世界”) 输出是 world hello world 世界 你好,世界
我认为应该谨慎使用这种技术,因为Scheme允许您这样做
(define (salute-english name) (display "Hello ") (display name))
(define (salute-french nom) (display "Salut ") (display nom))
现在,您可以通过将sallet
变量指定给右函数来重新定义函数,如sallet english
或sallet french
,如下所示:
(define salute salute-english)
(define (redefined-the-salute-function language)
(if (eq? language 'french)
(set! salute salute-french)
(set! salute salute-english)))
更一般的函数式编程语言允许您这样做,或者函数是第一类值。函数可以被操作,传递,有时分配给变量等等。该列表包括:Lisp、Scheme、Dylan、OCaml和SML。一些具有一流函数的语言包括Python,Ruby,Smalltalk,我认为Perl
请注意,如果您有一种交互式语言,可以在其中以交互方式键入程序,则必须能够重新定义函数/方法:REPL必须能够这样做,以防您碰巧重新键入已定义函数的定义。在PLSQL中:
create or replace procedure test
as
begin
execute immediate '
create or replace procedure test2
as
begin
null;
end;
';
end;
/
<>你可以用C++做,但是它不容易,安全,或者推荐。< /P>
create or replace procedure test
as
begin
execute immediate '
create or replace procedure test2
as
begin
null;
end;
';
end;
/
>>> def_string = 'def my_func'
>>> param_string_1 = '():'
>>> param_string_2 = '(x):'
>>> do_string_1 = ' print "Do whatever."'
>>> do_string_2 = ' print "Do something with", x'
>>> do_string_3 = ' print "Do whatever else."'
>>> do_string_4 = ' print "Do something else with", x'
>>> def_1 = '\n'.join([def_string+param_string_1, do_string_1, do_string_3])
>>> print def_1
def my_func():
print "Do whatever."
print "Do whatever else."
>>> exec def_1
>>> my_func()
Do whatever.
Do whatever else.
>>> def_2 = '\n'.join([def_string+param_string_2, do_string_2, do_string_4])
>>> print def_2
def my_func(x):
print "Do something with", x
print "Do something else with", x
>>> exec def_2
>>> my_func('Tom Ritter')
Do something with Tom Ritter
Do something else with Tom Ritter
>>>
def hello_world; puts "oops"; end
hello_world
# oops
def hello_world; puts "hello world"; end
hello_world
# hello world
require "benchmark"
# why oh _why
class Object
def metaclass; class << self; self; end; end
def meta_eval &blk; metaclass.instance_eval &blk; end
end
class Turtle
end
def make_it_move(klass)
klass.send(:define_method, :move) { |distance|
puts "moving #{distance} meters"
sleep(0.1 * distance)
}
end
make_it_move(Turtle)
turtle = Turtle.new
turtle.move(1)
# moving 1 meters
def profile(instance, method)
instance.meta_eval do
m = instance_method(method)
define_method method do |*a|
puts "Benchmarking #{instance.class} #{method}"
puts Benchmark.measure {
m.bind(instance).call(*a)
}
end
end
end
profile(turtle, :move)
turtle.move(10)
# Benchmarking Turtle move
# moving 10 meters
# 0.000000 0.000000 0.000000 ( 1.000994)
Turtle.new.move(3)
# moving 3 meters