[Moscow.pm] Почему и как это работает?

Андрей П. Ковбович akovbovich на gmail.com
Пн Авг 16 00:23:31 PDT 2010


Что не так с перлом (или со мной?) ? Или почему это работает именно так?

1) "foo {}" превращается в "do {} -> foo"

> perl -e 'package bar; sub foo { print "it works!\n" }; package main; foo {q/bar/}'
it works!

Как это видит интерпретатор:

> perl -MO=Deparse -e 'package bar; sub foo { print "it works!\n" }; package main; foo { bar }'
package bar;
sub foo {
    print "it works!\n";
}
package main;
do {
    'bar'
}->foo;
-e syntax OK

Судя по всему perl пытался осуществить вызов метода foo с
использованием косвенного объекта, в стиле METHOD INVOCANT (в отличие
от вызова в стиле INVOCANT->METHOD). Если спрятать определение bar, то
сразу становятся понятны намерения перла:

Can't locate object method "foo" via package "bar" (perhaps you forgot
to load "bar"?)

Заглянув в Camel Book узнал, что все-таки разрешается задавать
INVOCANT в виде блока при использовании формы косвенного объекта.

Непонятно только почему он заменил блок на конструкцию do {}... У do
{} семантика же в корне отличается от обычного блока BLOCK...


2) "foo->{'bar'}" превращается в "$foo{'bar'}"

> perl -e 'foo->{bar} = baz; print $foo{bar}'
baz

Как это видит интерпретатор:

> perl -MO=Deparse -e 'foo->{bar} = baz; print $foo{bar}'
$foo{'bar'} = 'baz';
print $foo{'bar'};
-e syntax OK

По идее, левым операндом для оператора "->" должна быть ссылка на хеш
(жесткая или символическая), в случае когда правый операнд является
индексом хеша. Откуда появился хеш %foo?

P.S. понятно, что use strict снимает все неоднозначности, но я
намеренно опустил его.


Подробная информация о списке рассылки Moscow-pm