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

Alex Varyanick q на cono.org.ua
Пн Авг 16 00:54:27 PDT 2010


2010/8/16 Андрей П. Ковбович <akovbovich на gmail.com>:
> Что не так с перлом (или со мной?) ? Или почему это работает именно так?
>
> 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...

Я не совсем понял что не понятно :)
Нам ведь нужен результат выполнения блока, его-то нам и возращает do.

> 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 снимает все неоднозначности, но я
> намеренно опустил его.

Осмелюсь предположить из этого:
perl -MO=Deparse -e '$foo->{bar} = baz'
$$foo{'bar'} = 'baz';

, что perl пытается выполнить link dereference на "foo" в контексте
HASH, от чего наверное получаем что-то типа: *foo{'HASH'}.

perl -MData::Dumper -e '*foo{HASH}->{bar} = baz; print Dumper \%foo'
$VAR1 = {
          'bar' => 'baz'
        };


-- 
Varyanick I. Alex
icq: 102 575 440
skype: cono..
q на cono.org.ua


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