Ответ Лиз полон полезной информации, и вы приняли ее, но я подумал, что следующее все еще может представлять интерес.
Как узнать, возвращает ли l-значение ...?
Давайте начнем с игнорирования предложения FALLBACK
.
Вам нужно будет проверить значение.Чтобы справиться с Scalar
s, вы должны проверить значение .VAR
.(Для не Scalar
значений .VAR
действует как "без операции".) Я думаю (но не цитируйте меня), что Scalar|Array|Hash
охватывает все значения l супертипы:
my \value = 42; # Int is an l-value is False
my \l-value-one = $; # Scalar is an l-value is True
my \l-value-too = @; # Array is an l-value is True
say "{.VAR.^name} is an l-value is {.VAR ~~ Scalar|Array|Hash}"
for value, l-value-one, l-value-too
Как узнать, возвращает ли значение l при использовании FALLBACK
?
Добавление«при использовании FALLBACK
» не имеет значения для ответа.
Как узнать, действительно ли мне нужно , чтобы вернуть l-значение ...?
Опять давайте начнем с игнорирования предложения FALLBACK
.
Это совершенно другой вопрос, чем "Как узнать, возвращает ли l-значение ..."?».Я думаю, что это суть вашего вопроса.
Афаик, ответ таков: вам нужно предвидеть, как будет использоваться возвращаемое значение.Если есть любой шанс, что он будет использоваться как l-значение , и вы хотите, чтобы это использование работало, тогда вам нужно вернуть l-значение ,Язык / компилятор не может (или, по крайней мере, не помогает) принять это решение.
Рассмотрим некоторые связанные сценарии:
my $baz := foo.bar;
... (100s of lines of code) ...
$baz = 42;
Если только первая строка не возвращает l-значение , вторая строка потерпит неудачу.
Но ситуация на самом деле гораздо более непосредственная, чем эта:
routine-foo = 42;
routine-foo
оценивается первым, полностью, до вычисления выражения lhs = rhs
.
Если только разрешение компилятора вызова routine-foo
не каким-то образом учитывает тот факт, что в ближайшее время произойдет то, что lhs
будетЕсли он будет назначен, то для однократно или многократно отправленного routine-foo
не будет возможности узнать, может ли он безопасно вернуть r-значение или должен возвращать l-значение .
И разрешение компилятора не включает это.Так, например:
multi term:<bar> is rw { ... }
multi term:<bar> { ... }
bar = 99; # Ambiguous call to 'term:<bar>(...)'
Я могу представить этот один день (через N лет), который решается комбинацией, позволяющей =
быть перегружаемым оператором, надежными макросамикоторые допускают перегрузку =
и возможность изменения стандартного разрешения, чтобы вышеуказанный неоднозначный вызов мог сделать что-то эквивалентное разрешению is rw
multi.Но я сомневаюсь, что на самом деле сбудется даже при N = 10.Возможно, есть другой способ, но я не могу придумать один в данный момент.
Как я могу узнать, действительно ли мне нужно возвращать l-значение , когдаиспользование FALLBACK
?
Снова добавление слова "при использовании FALLBACK
" не имеет значения для ответа.
Я хочу отслеживать, если я 'мы действительно изменили %!attrs
или только что прочитали значение при вызове FALLBACK
.
Когда вызывается FALLBACK
, он не знает, в каком контексте он вызывается - r-значение или l-значение .Любая модификация происходит после того, как она уже вернулась.
Другими словами, любое решение, которое вы придумали, само по себе не имеет ничего общего с FALLBACK
(даже если вам придется использовать его для реализации какого-либо другого аспектачто бы вы ни пытались сделать).
(Даже если бы это было так, я подозреваю, что попытка решить это с помощью FALLBACK
просто сделает дела хуже .два FALLBACK
multis, один с чертой is rw
, но, как объяснено выше, мое воображение не расширяется до того, чтобы что-то изменить в ближайшее время, если вообще когда-либо, и могло произойти, только если вышеперечисленные воображаемые вещи произошли (макросы и т. д.) и компилятор был также модифицирован, чтобы обратить внимание на два FALLBACK
мульти-варианта, и я вовсе не хочу утверждать, что это даже имеет смысл.)
План Б
Или (альтернативный план B) я могу прикрепить обратный вызов или что-то похожее на мой %!attrs
для отслеживания изменений?
Как отмечает Лизмат, это область Proxy
с.И, таким образом, ваш следующий ТАК вопрос ...:)