Прежде чем я углублюсь в ответ: большинство вещей в этом посте определяются реализацией, и реализация может определять их по-другому в будущем.
Чтобы выяснить, во что что-то (наивно) компилируется подRakudo Perl 6, используйте опцию --target=ast
(perl6 --target=ast foo.p6
).Например, связывание в:
class C {
has $!a;
submethod BUILD() {
my $x = [1,2,3];
$!a := $x
}
}
Получается как:
- QAST::Op(bind) :statement_id<7>
- QAST::Var(attribute $!a) <wanted> $!a
- QAST::Var(lexical self)
- QAST::WVal(C)
- QAST::Var(lexical $x) $x
При переключении на @!a
как здесь:
class C {
has @!a;
submethod BUILD() {
my $x = [1,2,3];
@!a := $x
}
}
Выходитas:
- QAST::Op(bind) :statement_id<7>
- QAST::Var(attribute @!a) <wanted> @!a
- QAST::Var(lexical self)
- QAST::WVal(C)
- QAST::Op(p6bindassert)
- QAST::Op(decont)
- QAST::Var(lexical $x) $x
- QAST::WVal(Positional)
Большая разница здесь заключается в инструкции decont
, и она будет принимать содержимое Proxy
, вызывая его FETCH
, поэтому контейнеризация исчезла.Таким образом, вы можете повторить поведение, вставив nqp::decont
вокруг Proxy
, хотя это скорее вызывает вопрос о том, что делает Proxy
, если правильный ответ получен без него!
Оба :=
и =
скомпилированы с использованием анализа случая (а именно, посмотрев на то, что находится слева).:=
работает только для ограниченного диапазона простых выражений слева;это явно оператор низкого уровня.Напротив, =
возвращается к вызову sub
, если анализ случая не предлагает более эффективную форму для генерации, хотя в большинстве случаев он управляет чем-то лучшим.
Анализ случая для:=
вставляет decont
, когда целью является лексический или атрибут с символом @
или %
, поскольку - на уровне Perl 6 - наличие элемента, связанного с @
или %
, не имеет смысла,Использование nqp::bindattr
поднимает уровень ниже семантики Perl 6, и поэтому возможно в конечном итоге получить Proxy
, привязанный непосредственно там, используя это.Тем не менее, это также нарушает ожидания в другом месте.Не ожидайте, что это пойдет хорошо (но, похоже, вы все равно не хотите этого делать).