[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