Главная страница


ru.cgi.perl

 
 - RU.CGI.PERL ------------------------------------------------------------------
 From : Andrey Sapozhnikov                   2:5020/400     15 Jul 2002  18:23:05
 To : Dmitry Koteroff
 Subject : Re: еще раз об экспорте   [Was: Открытое письмо...]
 -------------------------------------------------------------------------------- 
 
 Dmitry Koteroff wrote:
 
 > Если использовать только tie, то изменения в IN будут видны в пакете, но
 > изменения в пакете не будут видны в IN (я имею в виду изменения - добавления
 > новой переменной, а не изменение старой).  Или как-то можно выполнить tie и
 > для "стэша" (так, кажется, он называется?) того пакета?.. 
 
 Hет, для стэша tie не сделать. Да и не надо.
 
 > Просто хочется сделать $IN{a} и $IN'a полными синонимами в обе стороны.
 
 Для этого достаточно сделать tied %IN.
 
 ========================== PkgHash.pm =============================
 package PkgHash;
 use strict;
 use warnings;
 
 sub TIEHASH {
      my ($type, $pkg) = @_;
 
      unless ($pkg =~ /^main::.*::$/) {
          $pkg = "main$pkg" if  $pkg =~ /^::/;
          $pkg = "main::$pkg"  unless  $pkg =~ /^main::/;
          $pkg .= '::'     unless  $pkg =~ /::$/;
      }
 
      my($stem, $leaf) = $pkg =~ m/(.*::)(\w+::)$/;
      my $stem_symtab;
      {
   no strict "refs";
   $stem_symtab = *{$stem}{HASH};
      }
      die "Cannot find symtab for $pkg" unless
   defined $stem_symtab and exists $stem_symtab->{$leaf};
 
      bless {
          PACKAGE => $pkg,
          SYMTAB => *{$stem_symtab->{$leaf}}{HASH}
      }, $type;
 }
 
 sub FETCH {
      my ($self, $key) = @_;
      return unless exists $self->{SYMTAB}->{$key};
      local *sym = $self->{SYMTAB}->{$key};
      return *sym{HASH} || *sym{ARRAY} || ${*sym{SCALAR}};
 }
 sub STORE {
      my ($self, $key, $value) = @_;
      $key =~ /^[a-z_][\da-z_]*$/i or die "Wrong symbol name: $key";
      local *sym;
      {
   no strict "refs";
   *sym = *{$self->{PACKAGE} . $key};
      }
      *sym = $value if ref $value;
      *sym = \$value;
 }
 
 sub DELETE {
      my ($self, $key) = @_;
      exists $self->{SYMTAB}->{$key} or return;
      my $value = $self->FETCH($key);
      undef *{$self->{SYMTAB}->{$key}};
      delete $self->{SYMTAB}->{$key};
      $value;
 }
 
 sub CLEAR {
      my ($self) = @_;
      foreach (keys %{$self->{SYMTAB}}) {
   /^[a-z_][\da-z_]*$/i or next;
   undef *{$self->{SYMTAB}->{$_}};
   delete $self->{SYMTAB}->{$_};
      }
 }
 
 sub EXISTS {
      my ($self, $key) = @_;
      exists($self->{SYMTAB}->{$key});
 }
 
 sub FIRSTKEY {
      my ($self) = @_;
      $self->{KEYS} = {};
      my @keys = keys %{$self->{SYMTAB}};
      $self->{KEYS}->{$keys[$_]} = $keys[$_ + 1] foreach 0..$#keys;
      return $keys[0];
 }
 
 sub NEXTKEY {
      my ($self, $key) = @_;
      return $self->{KEYS}->{$key};
 }
 
 sub UNTIE {
      1;
 }
 
 sub DESTROY {
      1;
 }
 
 1;
 ============================== EOF ==========================
 ============================ test.pl ========================
 #!/usr/bin/perl -w
 use strict;
 use PkgHash;
 
 # Create package
 { package IN; }
 # Create hash
 our %IN;
 # Tie hash to class PkgHash
 tie %IN, 'PkgHash', 'IN';
 
 # ------------ Tests ---------------
 $IN::a = 'aaaaa';
 print "should be 'aaaaa' => ", $IN{a}, "\n";
 
 $IN::a .= 'bbbbb';
 print "should be 'aaaaabbbbb' => ", $IN{a}, "\n";
 
 $IN{a} .= 'ccccc';
 print "should be 'aaaaabbbbbccccc' => ", $IN::a, "\n";
 
 print exists($IN{a}) ? "\$IN{a} exists: OK\n" :
      "\$IN{a} not exists: Not OK\n";
 
 print "Was keys (should be a, b) => ", join(', ', keys %IN), "\n";
 
 print "Delete \$IN{a}\n";
 my $old = delete $IN{a};
 print "Old value (should be 'aaaaabbbbbccccc') => $old\n";
 
 print exists($IN{a}) ? "Delete: Not OK\n" :  "Delete: OK\n";
 print "Now keys (should be a) => ", join(', ', keys %IN), "\n";
 
 $IN{b} = 8;
 print "should be 8 =>", $IN::b, "\n";
 
 my %x = %IN::b;
 
 print "should be 8, but %IN::b autovivified, and we cannot " ,
      "detect which slot contains right data now... => $IN{b}\n";
 =========================== EOF ============================
 
 Вот рабочий скелет, только опасайтесь autovivify - он порождает
 переменную... тут уж ничего не сделать, кроме как поиграться
 с приоритетами - из какого слота данные актуальнее. Hапример
 сделать так:
 
 non-empty hash
 non-empty array
 defined scalar
 hash
 array
 undef scalar
 
 Андрей
 
 P.S. или бросить фигней заниматься. Hу чем просто хэш не устроил?
 Зачем еще неймспейс заводить?
 
 --- ifmail v.2.15dev5
  * Origin: Demos online service (2:5020/400)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 еще раз об экспорте [Was: Открытое письмо...]   Andrey Sapozhnikov   11 Jul 2002 21:15:11 
 Re: еще раз об экспорте [Was: Открытое письмо...]   Dmitry Koteroff   11 Jul 2002 23:00:53 
 Re: еще раз об экспорте [Was: Открытое письмо...]   Andrey Sapozhnikov   12 Jul 2002 13:23:22 
 Re: еще раз об экспорте [Was: Открытое письмо...]   Dmitry Koteroff   13 Jul 2002 19:24:22 
 Re: еще раз об экспорте [Was: Открытое письмо...]   Dmitry Koteroff   13 Jul 2002 19:22:20 
 Re: еще раз об экспорте [Was: Открытое письмо...]   Artem Chuprina   13 Jul 2002 22:45:42 
 Re: еще раз об экспорте [Was: Открытое письмо...]   Dmitry Koteroff   14 Jul 2002 00:23:05 
 Re: еще раз об экспорте [Was: Открытое письмо...]   Artem Chuprina   14 Jul 2002 10:32:21 
 Re: еще раз об экспорте [Was: Открытое письмо...]   Andrey Sapozhnikov   15 Jul 2002 18:23:05 
 Re: еще раз об экспорте [Was: Открытое письмо...]   Dmitry Koteroff   15 Jul 2002 18:57:51 
 Re: еще раз об экспорте [Was: Открытое письмо...]   Andrey Sapozhnikov   15 Jul 2002 19:24:36 
Архивное /ru.cgi.perl/52844346b304.html, оценка 1 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional