Едва ли jQuery только, но я сделал миленький мост для Ajax MS и jQuery:
Sys.UI.Control.prototype.j = function Sys$UI$Control$j(){
return $('#' + this.get_id());
}
действительно хорошо при выполнении большого количества Ajax ASP.NET так как jQuery поддерживается MS, теперь имеющим хорошие средства моста, что действительно легко сделать операции jQuery:
$get('#myControl').j().hide();
, Таким образом, вышеупомянутый пример не является большим, но если Вы пишете управление сервером Ajax ASP.NET, облегчает иметь jQuery в Вашей клиентской реализации управления.
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[1215 impression
Самомодифицирующийся код также называется вырожденным кодом. Обычно это считается плохим, и раньше целью языков высокого уровня было предотвратить его легкое написание.
Это из статьи в википедии:
Самомодифицирующийся код некоторые считают плохой практикой, которая затрудняет кодирование читать и поддерживать. Однако существуют способы, которыми самомодификация, тем не менее, считается приемлемой, например, когда указатели подпрограмм динамически изменяются - даже если эффект почти идентичен прямому изменению.
Я думаю, что так обстоит дело с большинством динамических языков. Вот пример на Python
def f(x): print x def new_function(x): print "hello", x f("world") f = new_function f("world")
. Результат -
world hello world
Я думаю, что такую технику следует использовать осторожно
Схема позволяет это сделать.
(define (salute-english name) (display "Hello ") (display name))
(define (salute-french nom) (display "Salut ") (display nom))
Теперь вы переопределяете функцию, назначая переменную salute
правой функции, либо salute-english
] или salute-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 .
Я всегда делал это в TCL, это было легко и прекрасно работало. Я мог исследовать какой-то интерфейс по сети, а затем на лету создать индивидуальный интерфейс для доступа и управления вещами. Например, вы можете создать собственный интерфейс SNMP из общей библиотеки SNMP.
Я не использовал его, но в C # есть встроенная поддержка для генерации собственного байтового кода, что довольно впечатляет.
Я делал такие вещи и на C, но там он непереносимый и почти никогда не стоит хлопот. Это метод, который иногда используется для "самооптимизирующегося" кода для генерации соответствующей функции C для оптимальной обработки заданного набора данных.
Вы могли бы сделать это на C ++, но это было бы нелегко, безопасно или рекомендовано.
В PLSQL:
create or replace procedure test
as
begin
execute immediate '
create or replace procedure test2
as
begin
null;
end;
';
end;
/
Достаточно просто на 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();
Думаю, это зависит от того, что именно вы определяете как «легко динамическое перезапись». Например, в .Net у вас есть тип Func и лямбда-выражения, которые позволяют вам определять функции как переменные или как временные анонимные функции, например.
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());
Выше приведен очень надуманный пример либо подсчета элементов в массиве целых чисел, либо последующего суммирования использование динамически создаваемых функций с произвольным условием.
Примечание. Не указывайте, пожалуйста, на то, что эти вещи могут быть легко выполнены без лямбда-выражений (что они, очевидно, могут). Я просто пытался написать очень простой пример, чтобы продемонстрировать концепцию в C #
Здесь есть кое-что еще в Python ( в дополнение к ответу luc), который я не рекомендую, а просто чтобы показать его - есть exec, который может выполнять строку, которую вы можете построить в виде любого кода ...
Показанный здесь ввод-вывод взят из Сеанс интерпретатора 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
>>>
Тривиально в Ruby:
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
Приведенный выше код:
Изменение того, что делает функция, поддерживается на многих языках, и это не так сложно, как вы думаете. В функциональных языках функции - это значения, а имена функций - это символы, которые связаны с ними, как с любой переменной. Если язык позволяет вам переназначить символ другой функции, это тривиально.
Я думаю, что более интересными функциями являются возможность получить исходный код для функции ( toString
выше) и создать новую функцию из строки (в данном случае eval
).