[Moscow.pm] Feature discussion: lvalue
Sergey Skvortsov
skv на protey.ru
Вс Апр 6 10:57:35 PDT 2008
Vladimir V. Perepelitsa wrote:
> У меня тут возникла мысль: как можно было-бы реализовать lvalue, чтоб и с
> обратной совместимостью и с расширением возможностией.
>
> смысл такой:
> {
> my $var
> sub accessor : lvalue {
> return sub {
> if ( @_ ) { $var = shift }
> return $var;
> }
> }
> }
>
> т.е. если lvalue subroutine возвращает CODE, то этот CODE вызывается с правыми
> аргументами.
> Т.е. при accessor() = 10;
> вызывается ANON->(10);
>
> Кто ковырялся во внутренностях перла, можете сказать, насколько сложно такое
> реализовать?
Вообще затея imho бессмысленная, поскольку lvalue - это всегда
определённый overhead.
В pure-perl это сделать нельзя. Через XS - можно:
1. accessor() должен возвращать SV типа SVt_PVLV, с выставленным
SET-MAGIC и выставленной ссылкой в lvalue target на anon sub; также
выставляем обработчик для собственно magic'а - скажем set_lvalue_vtbl.
Код выглядит примерно так (sv - это то, что возвращает accessor):
SvSMAGICAL_on(sv);
LvTYPE(sv) = '~';
LvTARG(sv) = SvREFCNT_inc( anon_cv );
SvMAGIC(sv)->mg_virtual = &set_lvalue_vtbl;
2. Сам обработчик будет делать собственно вызов:
int set_lvalue_func(pTHX_ SV *sv, MAGIC* mg);
static struct mgvtbl set_lvalue_vtbl={
0, set_lvalue_func,
0, 0, 0,
#if defined(PERL_REVISION) && PERL_VERSION >= 8
0, 0,
#endif
};
int set_lvalue_func(pTHX_ SV *sv, MAGIC* mg) {
// валидируем sv, если оно надо
if(!SvOK(sv))
croak("only defined value can be assigned");
cv = LvTARG(sv); // берём ссылку на anon sub
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs( sv ); // передаём один лишь аргумент
PUTBACK;
(void)perl_call_sv(cv, G_SCALAR); // ждём зачем-то результат
SPAGAIN;
resultSV = POPs;
// что-то делаем с resultSV? например, куда-то его присваиваем?
PUTBACK;
FREETMPS;
LEAVE;
return TRUE;
}
-------
Это только эскиз, масса деталей опущено, часть моментов надо проверить
на практике - но реальный тест мне делать лениво :)
--
Sergey Skvortsov
mailto: skv на protey.ru
Подробная информация о списке рассылки Moscow-pm