Редактирование web.config
файл или обновление DLL в bin
папка просто перерабатывает рабочий процесс для того приложения, не целый пул.
Нет, нельзя. Какую основную проблему вы пытаетесь решить? Возможно, есть какой-то способ сделать то, что есть.
Повторите добавленную часть вопроса «Ваш ответ может включать XS, если необходимо, но я бы предпочел этого не делать», вызывать встроенные команды из XS действительно сложно, так как встроенные команды настроены так, чтобы предполагать, что они работают как часть скомпилированного optree и имеют определенные глобальные переменные. Обычно гораздо проще вызвать некоторую базовую функцию, которую использует сама встроенная функция, хотя такая функция не всегда, поэтому вы видите такие вещи, как:
buffer = sv_2mortal(newSVpvf("(caller(%d))[3]", (int) frame));
caller = eval_pv(SvPV_nolen(buffer), 1);
(выполнение строки eval из XS вместо того, чтобы проходить через обручи, необходимые для непосредственного вызовите pp_caller).
Вы можете сделать это, если сначала пропатчите внутренний метод (который даст вам кодовую ссылку вашего патча):
use strict;
use warnings;
BEGIN {
*CORE::GLOBAL::die = sub { warn "patched die: '$_[0]'"; exit 3 };
}
print "ref to patched die: " . \&CORE::GLOBAL::die . "\n";
die "ack, I am slain";
дает результат:
ref to patched die: CODE(0x1801060)
patched die: 'ack, I am slain' at patch.pl line 5.
BTW: Я бы признателен, если кто-нибудь может объяснить, почему переопределение должно выполняться как * CORE :: GLOBAL :: die
, а не * CORE :: die
. Я не могу найти никаких ссылок по этому поводу. Кроме того, почему переопределение должно выполняться в блоке BEGIN? Вызов die () выполняется во время выполнения, так почему нельзя выполнить переопределение непосредственно во время выполнения?
Вы можете обернуть shift чем-то, на что вы можете сослаться, но вы должны использовать прототип, чтобы использовать его, поскольку shift особенный.
sub my_shift (\@) { my $ll = shift; return shift @$ll }
Проблема в том, что система-прототип не может волшебным образом понять, что когда она вызывает некоторую случайную ссылку на подпрограмму в скаляре, она должна принять ссылку перед вызовом подпрограммы.
my @list = (1,2,3,4);
sub my_shift (\@) { my $ll = shift; return shift @$ll }
my $a = shift @list;
my $my_shift_ref = \&my_shift;
my $b = (&{$my_shift_ref} (\@list) ); # see below
print "a=$a, b=$b\n";
for (my $i = 0; $i <= $#list; ++$i) { print "\$list[$i] = ",$list[$i],"\n"; }
Если это вызывается как просто @list
, perl barfs, потому что он не может автоматически создавать ссылки, как это делает shift
.
См. Также: [ http://www.perl.com/language/misc/ fmproto.html] [Статья Тома Кристенсена].
Конечно, для встроенных функций, которые не являются особенными, как shift, вы всегда можете сделать
sub my_fork { return fork; }
, а затем & my_fork
все, что захотите.
Я экспериментировал с решениями общего назначения для этого и придумал следующий грязный прием с использованием eval. Он в основном использует прототип, чтобы отделить @_, а затем вызвать встроенный. Это было только слегка протестировано и использует строковую форму eval, поэтому некоторые могут сказать, что он уже сломан: -)
use 5.10.0;
use strict;
use warnings;
sub builtin {
my ($sub, $my, $id) = ($_[0], '');
my $proto = prototype $sub //
prototype "CORE::$sub" //
$_[1] //
($sub =~ /map|grep/ ? '&@' : '@;_');
for ($proto =~ /(\\?.)/g) { $id++;
if (/(?|(\$|&)|.(.))/) {
$my .= "my \$_$id = shift;";
$sub .= " $1\$_$id,";
} elsif (/([@%])/) {
$my .= "my $1_$id = splice \@_, 0, \@_;";
$sub .= " $1_$id,";
} elsif (/_/) {
$my .= "my \$_$id = \@_ ? shift : \$_;";
$sub .= " \$_$id,"
}
}
eval "sub ($proto) {$my $sub}"
or die "prototype ($proto) failed for '$_[0]', ".
"try passing a prototype string as \$_[1]"
}
my $shift = builtin 'shift';
my @a = 1..10;
say $shift->(\@a);
say "@a";
my $uc = builtin 'uc';
local $_ = 'goodbye';
say $uc->('hello '), &$uc;
my $time = builtin 'time';
say &$time;
my $map = builtin 'map';
my $reverse = builtin 'reverse';
say $map->(sub{"$_, "}, $reverse->(@a));
my %h = (a=>1, b=>2);
my $keys = builtin 'keys';
say $keys->(\%h);
# which prints
# 1
# 2 3 4 5 6 7 8 9 10
# HELLO GOODBYE
# 1256088298
# 10, 9, 8, 7, 6, 5, 4, 3, 2,
# ab
Исправлено с помощью ниже и отредактировано.
Насколько я понимаю, вы хотите иметь ссылку на код, которая будет вызываться для некоторых данных и может указывать на какую-то вашу функцию или встроенную функцию.
Если я прав, просто укажите встроенное в закрытие:
#!/usr/bin/perl -w
use strict;
my $coderef = \&test;
$coderef->( "Test %u\n", 1 );
$coderef = sub { printf @_ };
$coderef->( "Test %u\n", 2 );
exit;
sub test {
print join(' ', map { "[$_]" } @_) . "\n";
}
Выполнение этого со сдвигом также возможно, но помните, что сдвиг без явного массива для работы работает с разными массивами в зависимости от того, где он был вызван.
Если вы хотите увидеть, что нужно для подделки в производственном коде качества, посмотрите код для autodie . Мясо находится в Fatal . Помогает, если вы безумный пират-джедай из Австралии.
Единственный способ заставить его работать - это сделать ссылку на sub {shift}
.
perl -e '@a=(1..3); $f=sub{shift}; print($f->(@a), "\n");'
Функционально это эквивалентно:
perl -e '@a=(1..3); print(shift(@a), "\n");'
Что могло бы быть просто perl -e 'print 1, "\ n"'
, но тогда мы не будем говорить о встроенной функции.
К вашему сведению, я удивлен, что нельзя ссылаться на встроенную команду, и теперь, когда мне стало ясно, я не могу не думать об этом как о недостатке Perl.
Update Эрик правильно указывает, что $ f = sub {shift}; $ f -> (@ a)
оставляет @a
без изменений. Это должно быть больше похоже на:
perl -e '@a=(1..3); $f=sub{shift @{+shift}}; print($f->(\@a), "\n");
Спасибо, Эрик.