哪些语言可以动态地在飞行重写的功能呢?(In what languages can you dyna

2019-09-18 11:47发布

我最近在重写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 to export to excel</div>

我不能改变输出HTML,但我需要一个额外的参数添加到该链接。 我开始思考这个问题,并意识到我可能只是这样做:

excelExport = $('excelExport1234');
if (needParam)
        eval('excelExport.onclick = ' + excelExport.onclick.toString().replace("excelReport.aspx?id", "excelReport.aspx?extraParam=true&id") + ';');
else
        eval('excelExport.onclick = ' + excelExport.onclick.toString().replace("extraParam=true&", "") + ';');

和它的工作就像一个冠军! excelExport.onclick返回一个函数对象,我转换为字符串,并做一些字符串MANIP。 因为它现在的形式“功能(){...}”,我刚回去,并将其分配给DOM对象的onclick事件。 这是一个有点难看不必使用eval,但据我所知没有一个javascript函数的构造,可以采取一串代码,并把它变成一个对象很好。

不管怎样,我的观点是不是说我是超级聪明(我不是),我的观点是, 这是很酷的 。 我知道的JavaScript是不是能够做到这一点的唯一语言。 我听说口齿不清已宏年这一确切目的。 除了真正神交宏,你需要真正神交口齿不清,我不神交,我只是“种得到它”。

所以我的问题是: 在什么其他语言你能(轻松)动态重写功能,你能告诉我一个简单的例子? 我想看看还有什么地方你能做到这一点,它是如何做!

(另外,我不知道这个标签作为,所以我把随机猜测)

Answer 1:

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的权力的最有趣的陈列柜在其宏系统。 我真的不觉得我可以做专题公正,所以如果你有兴趣阅读这些链接:

http://en.wikipedia.org/wiki/Macro_(computer_science)#Lisp_macros

http://cl-cookbook.sourceforge.net/macros.html



Answer 2:

我想这取决于究竟你定义为“轻松动态重写”。 例如,在.net中,您有Func键型和lambda表达式,它允许您定义功能变量或临时匿名函数如。

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());

以上是任一计数项目中一个整数数组,或使用动态创建的功能受到一些任意条件求和然后非常人为的例子。

注-请不要指出的是,这些东西可以在不lambda表达式很容易地完成(其中他们显然可以)我只是想写一个很简单的例子来演示在C#概念



Answer 3:

自修改代码也被称为退化的代码。 这通常被认为是一件坏事,它曾经是高级语言的一个目标,以防止它被随便写。

这是从维基百科条目:

自修改代码是被一些人视为一种不好的做法,这使得代码难于阅读和维护看到。 然而有方式,其中自修改仍然被认为是可接受的,例如子程序指针时被动态地改变的 - 即使效果几乎是相同的直接修改。



Answer 4:

我认为这是大多数动态语言的情况。 这里是在Python一个例子

def f(x):
    print x

def new_function(x): print "hello", x

f("world")    
f = new_function
f("world")

输出是

world
hello world

我认为,这样的技术应谨慎使用



Answer 5:

计划可以让你做到这一点。

(define (salute-english name) (display "Hello ") (display name))
(define (salute-french nom) (display "Salut ") (display nom))

现在,您可以通过分配重新定义fonction salute变量为正确的函数,要么salute-englishsalute-french ,像这样:

(define salute salute-english)

(define (redefined-the-salute-function language)
  (if (eq? language 'french)
      (set! salute salute-french)
      (set! salute salute-english)))

更多generaly函数式编程语言允许你这样做或功能是一流的价值。 功能可以被操纵,传来传去,有时赋值给变量等。 然后,名单包括:Lisp语言计划迪伦 ,OCaml中SML。 具有一流的功能有些语言包括PythonRuby,Smalltalk和我想的Perl。

需要注意的是,当你有一个互动的语言,你可以交互地输入程序,功能的重新定义/方法必须是可能的:REPL必须能够做到这一点,以防万一你发生重新输入的已定义函数的定义。



Answer 6:

我以前在TCL做这一切的时候,它是一个微风和表现的很出色。 我可以调查通过网络出头接口,然后动态创建一个定制的接口来访问和控制的事情。 例如,你可以把从一个普通的SNMP库自定义的SNMP接口。

我没有用它,但是C#有一些内置生成它自己的字节码,这是相当可观的支持。

我已经做了这样的事情在C作为很好,但它是不可移植的,几乎从来不值得冒这个险。 它有时是用于“自优化”的代码,以生成相应的C函数以最佳方式处理给定的数据集的技术。



Answer 7:

你能做到这一点在C ++中,但它不会是容易的,安全的,或推荐。

  1. 生成的源代码的文本
  2. 调用编译器(叉&EXEC)来构建动态库。 在海湾合作委员会,你可以把你想要编译标准输入的源代码,它并不一定要在一个文件中。
  3. 负载(在Linux上的窗口调用LoadLibrary(),dlopen的())库
  4. 得到一个函数指针,以任何你想要的功能(在Linux GetProcAddress的()在Windows上,则dlsym())
  5. 如果要替换现有的功能,如果它是一个虚函数,你可以修改v表指向新的功能(该部分特别是一个可怕的想法充满了危险)。 V型表或它的格式的位置是不是C ++标准的一部分,但我使用的所有工具链并没有超出自己保持一致,所以一旦你弄清楚他们如何做到这一点,它可能不会打破。


Answer 8:

很容易,在Perl。

*some_func = sub($) {
    my $arg = shift;
    print $arg, "\n";
};
some_func('foo');

重新萨姆藏红花的要求:

*hello_world = sub() {
    print "oops";
};
hello_world();
*hello_world = sub() {
    print "hello world";
};
hello_world();


Answer 9:

在PLSQL:

create or replace procedure test
as
begin
 execute immediate '
create or replace procedure test2
as
begin
  null;
end;
 ';
end;
/


Answer 10:

下面是其他的东西在Python(除了LUC的答案),这我不建议,但只是为了显示它 - 有EXEC,可以执行,你可以建立成为任何代码串...

I / O此处显示为一个Python 2.5.2解释器会话。 只是构建字符串的一些简单的例子,从子执行(>>>是提示符的解释)...

>>> 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
>>> 


Answer 11:

平凡的红宝石:

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 

上面的代码:

  1. 定义一个类空白
  2. 添加一个方法,它
  3. 抓住一个实例
  4. 截获在该实例方法


Answer 12:

改变什么功能确实在很多语言的支持,并且它并不像你想象的那么复杂。 在功能性的语言,函数是值和函数名是被绑定到这些像任何变量的符号。 如果语言允许您将符号重新分配给不同的功能,这是微不足道的。

我觉得更有趣的功能是得到一个功能的源代码(能力toString以上),并从字符串(创建一个新的功能eval在这种情况下)。



文章来源: In what languages can you dynamically rewrite functions on the fly?