X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2Ffields.pm;h=a64469c161f5a45e289ef92f7fbf879e8ffaf648;hb=c9bca74aca217023baf0f921dcffaaa072a83cf3;hp=5a84e28f2e22f2c173d4bb8afe0de181fc2b20bd;hpb=33e06c89116da420821234eb364a70b215b00a8d;p=p5sagit%2Fp5-mst-13.2.git diff --git a/lib/fields.pm b/lib/fields.pm index 5a84e28..a64469c 100644 --- a/lib/fields.pm +++ b/lib/fields.pm @@ -21,10 +21,10 @@ fields - compile-time class fields } } - my Foo $var = Foo::->new; + my $var = Foo->new; $var->{foo} = 42; - # this will generate a compile-time error + # this will generate an error $var->{zap} = 42; # subclassing @@ -51,11 +51,6 @@ hash of the calling package, but this may change in future versions. Do B update the %FIELDS hash directly, because it must be created at compile-time for it to be fully useful, as is done by this pragma. -If a typed lexical variable holding a reference is used to access a -hash element and a package with the same name as the type has declared -class fields using this pragma, then the operation is turned into an -array access at compile time. - The related C pragma will combine fields from base classes and any fields declared using the C pragma. This enables field inheritance to work properly. @@ -65,26 +60,21 @@ the class and are not visible to subclasses. Inherited fields can be overridden but will generate a warning if used together with the C<-w> switch. -The effect of all this is that you can have objects with named fields -which are as compact and as fast arrays to access. This only works -as long as the objects are accessed through properly typed variables. -If the objects are not typed, access is only checked at run time. - The following functions are supported: =over 8 =item new -fields::new() creates and blesses a pseudo-hash comprised of the fields -declared using the C pragma into the specified class. +fields::new() creates and blesses a restricted-hash comprised of the +fields declared using the C pragma into the specified class. This makes it possible to write a constructor like this: package Critter::Sounds; use fields qw(cat dog bird); sub new { - my Critter::Sounds $self = shift; + my $self = shift; $self = fields::new($self) unless ref $self; $self->{cat} = 'meow'; # scalar element @$self{'dog','bird'} = ('bark','tweet'); # slice @@ -93,46 +83,26 @@ This makes it possible to write a constructor like this: =item phash -fields::phash() can be used to create and initialize a plain (unblessed) -pseudo-hash. This function should always be used instead of creating -pseudo-hashes directly. - -If the first argument is a reference to an array, the pseudo-hash will -be created with keys from that array. If a second argument is supplied, -it must also be a reference to an array whose elements will be used as -the values. If the second array contains less elements than the first, -the trailing elements of the pseudo-hash will not be initialized. -This makes it particularly useful for creating a pseudo-hash from -subroutine arguments: - - sub dogtag { - my $tag = fields::phash([qw(name rank ser_num)], [@_]); - } - -fields::phash() also accepts a list of key-value pairs that will -be used to construct the pseudo hash. Examples: - - my $tag = fields::phash(name => "Joe", - rank => "captain", - ser_num => 42); - - my $pseudohash = fields::phash(%args); +Pseudo-hashes have been removed from Perl as of 5.10. Consider using +restricted hashes instead. Using fields::phash() will cause an error. =back =head1 SEE ALSO L, -L =cut -use 5.005_64; +use 5.006_001; use strict; no strict 'refs'; +use warnings::register; our(%attr, $VERSION); -$VERSION = "1.01"; +$VERSION = "1.02"; + +use Hash::Util qw(lock_keys); # some constants sub _PUBLIC () { 1 } @@ -171,7 +141,7 @@ sub import { if ($fno and $fno != $next) { require Carp; if ($fno < $fattr->[0]) { - Carp::carp("Hides field '$f' in base class") if $^W; + warnings::warnif("Hides field '$f' in base class") ; } else { Carp::croak("Field name '$f' already in use"); } @@ -245,40 +215,13 @@ sub _dump # sometimes useful for debugging sub new { my $class = shift; $class = ref $class if ref $class; - return bless [\%{$class . "::FIELDS"}], $class; + my $self = bless {}, $class; + lock_keys(%$self, keys %{$class.'::FIELDS'}); + return $self; } sub phash { - my $h; - my $v; - if (@_) { - if (ref $_[0] eq 'ARRAY') { - my $a = shift; - @$h{@$a} = 1 .. @$a; - if (@_) { - $v = shift; - unless (! @_ and ref $v eq 'ARRAY') { - require Carp; - Carp::croak ("Expected at most two array refs\n"); - } - } - } - else { - if (@_ % 2) { - require Carp; - Carp::croak ("Odd number of elements initializing pseudo-hash\n"); - } - my $i = 0; - @$h{grep ++$i % 2, @_} = 1 .. @_ / 2; - $i = 0; - $v = [grep $i++ % 2, @_]; - } - } - else { - $h = {}; - $v = []; - } - [ $h, @$v ]; + die "Pseudo-hashes have been removed from Perl"; } 1;