о Perl

Mar. 14th, 2005 05:10 pm
yorool_gui: (Default)
[personal profile] yorool_gui
Перл замечательный язык, когда на нем пишу Я. Когда на нем пишут другие -- это кошмар. И подозреваю, что это взаимно.

use strict;
...
no strict 'refs';
...
$self->{LABELS}->{$title} = $3;
$self->{LABELS}->{$title}->{NUM} = $num++;

Это работатет. Но я не понимаю, ради чего надо так извращаться. Это не тот Перл, на котором пишу я. На моем Перле ref $self->{LABELS}->{$title} будет либо SCALAR, либо HASH, но никак не то и другое одновременно. А вот на Перле этого человека в $self->{LABELS}->{$title} хранятся сразу два значения и ему это удобно. Но это другой язык.

Date: 2005-03-14 02:16 pm (UTC)
From: [identity profile] blacklion.livejournal.com
А я бы за другое убил -- за no strict 'refs';. Т.е. я просто отказываюсь понимать этот код. Сначала присваеаыем скалярь, а потом обращаемся к нему как к hash ref! Нет, я понимаю, как оно работает, но за любоею no strict (включая LABELS/NUM без кавычек) -- убивать.

Date: 2005-03-14 02:21 pm (UTC)
From: [identity profile] sorhed.livejournal.com
У меня в одном месте no strict таки пользуется. Но я его уберу, если вы скажете, как можно без no strict refs обратиться к $AUTOLOAD :)

Date: 2005-03-14 02:23 pm (UTC)
From: [identity profile] blacklion.livejournal.com
Да, это, пожалуй, единственный пример... Но тут явно не тот случай.

Date: 2005-03-14 02:27 pm (UTC)
From: [identity profile] sorhed.livejournal.com
Ну, не только. Иногда (например, в коде одной извращённой штуки, которая использует собственную нестандартную модель наследования) бывают нужны symbolic references. Случаи, конечно, единичные. Но бывают.

(хотя, конечно, всё равно было бы неплохо, чтобы strict шёл по дефолту, а извращенцы вроде меня использовали бы no strict в специально отведённых местах).

Date: 2005-03-14 02:29 pm (UTC)
From: [identity profile] blacklion.livejournal.com
(например, в коде одной извращённой штуки, которая использует собственную нестандартную модель наследования)
А вот какова необходимость в том, что бы она была такая ивзращенная?

Date: 2005-03-14 02:32 pm (UTC)
From: [identity profile] sorhed.livejournal.com
Очень просто.
Где-то в недрах perldoc perlobj сказано, что если менять @ISA динамически где ни попадя, то ничего хорошего из этого не выйдет, так как оно там кэшируется. А мне как раз надо было динамически. Чтобы если девелопер захотел в живой системе созданный объект унаследовать от чего-нибудь ещё — то нет проблем.

Date: 2005-03-14 02:37 pm (UTC)
From: [identity profile] blacklion.livejournal.com
А может лучше тогда переписать на python? :)
Вообще, плохо понимаю, зачем такое может понадобится и почему тогда это не реализовать через AUTOLOAD в виде модуля Class::DynamicInheritance какого-нибудь, от которого наследоватьв се такие классы...

Date: 2005-03-14 02:40 pm (UTC)
From: [identity profile] sorhed.livejournal.com
Да я так почти и сделал.
Ну, в общем, вот о чём я говорю:

sub AUTOLOAD {
    my ($this) = @_;
    my $method_name = $AUTOLOAD;
    $method_name =~ s/^(.*):://;
    my $class_name = $1;
    $class_name =~ s/^(.*):://;
    my $package_name = $1;
    my $method = $this->get_method($method_name, $class_name);
    if ($method) {
        my $code = $method->{code};
        my $result = eval ($code);
        if ($@) { $this->error($@); }
        return $result; 
    } else {
        $this->error("Method $method_name for $class_name is not found.");
    }
}

sub get_method {
    my ($this, $method_name, $class_name) = @_;
    my $class = $this->{STORAGE}->get_class($class_name);
    my $class_id = $class->{class_id};
    my $method = $this->{STORAGE}->get_object(-name => $method_name,
                                      -class => 'Method', 
                                      -of_class => $class_id);
    if ($method) {
        return $method;
    } else {
        if ($class_name ne 'Object') {
            my $parent_class_id = $class->{parent};
            my $parent_class_name = 
                    $this->{STORAGE}->get_class($parent_class_id)->{name};
            return $this->get_method($method_name, $parent_class_name);
        } else {
            return undef;
        }
    }     
}

Date: 2005-03-14 02:46 pm (UTC)
From: [identity profile] blacklion.livejournal.com
Бррр... Не вижу здесь не-стриктных референсов... Хотя eval($code) не очень понял зачем нужно, почему не $code(). Или там оно действительно строкой хранится?

Date: 2005-03-14 02:48 pm (UTC)
From: [identity profile] sorhed.livejournal.com
Строкой. Из базы же достаётся.
А нестриктные референсы я всё-таки убрал, оказывается :) Блин, вот что значит три месяца в код не заглядывать.

Date: 2005-03-14 02:54 pm (UTC)
From: [identity profile] blacklion.livejournal.com
А, ну из базы -- тогда да :) Это, как ты понимаешь, неочевидно из этого куска кода.

Хотя, производительность так должна страдать...

Date: 2005-03-14 02:55 pm (UTC)
From: [identity profile] sorhed.livejournal.com
Есессно. Но Cache::Memcached никто не отменял.

Date: 2005-03-14 02:59 pm (UTC)
From: [identity profile] blacklion.livejournal.com
Это ничем не поможет тормознутости eval "code"; или ты про кеширование результатов?

Date: 2005-03-14 03:00 pm (UTC)
From: [identity profile] sorhed.livejournal.com
И того, и другого, и можно без хлеба а ещё я где-то слышал, что после эвала можно просто хранить ссылки на code references, только не знаю пока ещё, как :)

Date: 2005-03-14 03:09 pm (UTC)
From: [identity profile] blacklion.livejournal.com
Вот последнее очень интересно. В JavaScript я просто скажу

var code = new Function( "some code; goes; here;" );

А про Perl -- Я как раз только что думал, как бы получить CodeV из eval'а... Вот так, сходу, способа не вижу... Т.е. вижу, но кривой до невозможности:

sub getCode
{
  my $code = $_[0];
  local *F;
  my $name = sprintf( "__getCode_unique_name_0x%08x_%s", $$, md5_hex($code) );
  open(F, "> /var/tmp/$$.pl");
  print F "sub ", $name, " { ";
  print F $code;
  print F "}";
  close(F);
  require "/var/tmp/$$.pl";
###
# DAMN!
  {
    no strict 'ref';
    $code = \&{$name};
  }
###
  unlink("/var/tmp/$$.pl");
  return $code;
}

Но ведь крииииво... И будет ли работать... Ччерт, давно на перле не писал...

Date: 2005-03-14 03:14 pm (UTC)
From: [identity profile] sorhed.livejournal.com
В общем, если нужен источник вдохновения — рекомендую зайти на www.everydevel.com и скачать оттуда Everything Core (на котором, кстати, построен всеми нами любимый perlmonks.org). Я лично уже года два тягаю оттуда идеи :)

Date: 2005-03-14 03:19 pm (UTC)
From: [identity profile] blacklion.livejournal.com
Так не интересно :)

Date: 2005-03-14 03:25 pm (UTC)
From: [identity profile] blacklion.livejournal.com
ХА! Все проще! Прочел perldoc -f do внимательно (придя оттуда из perldoc -f require) и родил слкедюущую работающую конструкцию:


my $codeRef = eval "sub { $codeStr } ";

ВСЕ! Работает!

Date: 2005-03-14 03:27 pm (UTC)
From: [identity profile] sorhed.livejournal.com
Гы, логично :)

Date: 2005-03-15 08:28 am (UTC)
From: [identity profile] co108.livejournal.com
ой, а что вы за гарево-погарево тут делаете если не секрет? пишите перл++ на перле? :))

Date: 2005-03-15 11:27 am (UTC)
From: [identity profile] sorhed.livejournal.com
Хуже. Smalltalk (точнее, Gemstone/S) на перле :)

Date: 2005-03-14 02:30 pm (UTC)
From: [identity profile] sorhed.livejournal.com
Кстати, а за такое тоже убивают? :)

$possibly_unititalized ||= 'default_value';

Date: 2005-03-14 02:32 pm (UTC)
From: [identity profile] blacklion.livejournal.com
Нет, IMHO. Это классический паттерн, вроде "*p++ = *q++;" в C. т.е. хакерство, но уже ставшее идиомой языка.

Date: 2005-03-14 02:22 pm (UTC)
From: [identity profile] asd.livejournal.com
Всегда в начале скрипта писать:

use strict;
use utf8;
use warnings FATAL => 'uninitialized';


Это спасает от безумного кода :)

Date: 2005-03-14 02:22 pm (UTC)
From: [identity profile] blacklion.livejournal.com
Именно.

Date: 2005-03-14 02:26 pm (UTC)
From: [identity profile] yorool-gui.livejournal.com
Как раз и LABELS и NUM без кавычек отлично работает и при полном use strict. Я сам этим постоянно пользуюсь -- никаких проблем это не порождает, просто syntax sugar.
А вот no strict 'refs' -- это да. Я около часа тоже этот код понимать просто отказывался, тем более что no strict 'refs' было не сразу под use strict, а пятью строчками ниже, куда я сначала не поглядел.
Я, кстати, так толком и не пониямаю, как это работает. Не, я помню что-то про хитрые структуры, в которых хранятся перловые переменные и догадываюсь, что они просто хранят там два значения для разных типов. Но что вернет ref на такую переменную -- не понимаю.

Date: 2005-03-14 02:28 pm (UTC)
From: [identity profile] blacklion.livejournal.com
ref -- ссылку на скаляр. А если мы обращаемся к нему как к хэшу, оно ищет, нету ли хэша с таким именем.

А вот без кавычек -- да, работает всегда. Но все равно очень не люблю. Потому что для меня идентификатор без типа в перле -- это однозначно константа (use constant { LABEL => 1, NUM => 2 };)

Date: 2005-03-14 02:51 pm (UTC)
From: [identity profile] yorool-gui.livejournal.com
именно это я и имел в виду в исходном посте, насчет взаимно-кошмарного кода :-)

Date: 2005-03-14 02:56 pm (UTC)
From: [identity profile] sorhed.livejournal.com
Ну, кстати, вы же не будете утверждать, что $hashref->{some_key} — это однозначное зло? :) Мне всегда было лень писать $hashref->{'some_key'}, тем более, и strict смотрит на это сквозь пальцы.

Date: 2005-03-14 02:59 pm (UTC)
From: [identity profile] blacklion.livejournal.com
Однозначного зла вовсе нет :)

Да, это минорное зло. Я уже привык в чужом коде. Но сам не ленюсь :)

Date: 2005-03-14 04:35 pm (UTC)
From: [identity profile] yorool-gui.livejournal.com
Блин, я только сейчас разобрался, что же там происходит. Там же глобальные переменные засирались как из гамномета, причем если попадались одинаковые значения, то они и отображались на одну и ту же переменную, отчего происходил Реальный Геморрой. Теперь мне все ясно, а исходный пост признается ересью.

Profile

yorool_gui: (Default)
Michael Ilyin

April 2017

S M T W T F S
      1
2 345678
910 1112131415
16171819202122
23242526272829
30      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Sep. 21st, 2025 04:09 am
Powered by Dreamwidth Studios