in reply to Re: Fields pragma - the poor man's OO framework?
in thread Fields pragma - the poor man's OO framework?

I've done so carefully before posting, and as far as I can see the interface (fields::new()) and features are still the same. The only difference is that field access is no longer faster in 5.10, as I stated above.

So I'm still wondering: if one has to use plain blessed hashes, is there any reason not to get some static checks with fields?


Anonymous, holli and dragonchild: I'm perfectly aware of the benefits that come with modern OO frameworks, as I use Object::InsideOut in my own projects. However, for various reasons that I don't want to discuss on a public forum, I cannot use them here (openly or otherwise).

Replies are listed 'Best First'.
Re^3: Fields pragma - the poor man's OO framework?
by perrin (Chancellor) on Jul 06, 2008 at 22:03 UTC
    It's fine to use this module, although things like Class::Accessor are generally more popular. However, don't expect any compile-time checking and don't use that "my Type $foo" syntax since that's all pseudo-hashes.
Re^3: Fields pragma - the poor man's OO framework?
by dragonchild (Archbishop) on Jul 07, 2008 at 00:56 UTC
    If you want static checks, don't use fields. Use something like Tie::Hash::FixedKeys.
    use Tie::Hash::FixedKeys; my @keys = qw( a b c ); sub new { my $class = shift; my %args = @_; my $self = {}; tie %$self, 'Tie::Hash::FixedKeys', @keys; foreach my $k ( @keys ) { if ( exists $args{$k} ) { $self->{$k} = $args->{$k}; } } return bless $self, $class; }
    Now, you have all the benefits of static fieldname checking without going into the depths of a deprecated feature. Maybe it's just me, but I'd strongly prefer that.

    Of course, the better solution is to create your own OO framework that auto-generates mutators based on some static list of mutator names. Writing one is the matter of a couple hours. You can even crib heavily from CPAN and call it your own work. That way, everything is a method call. Direct attribute access is horrible practice.


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
      'static' in this context means 'checked at compile time' rather than 'restricted to a given set of values'.

      However if restriction to given values is wanted, I'd suggest Hash::Utils as it is core in 5.8 and above (and it does the restriction natively rather than using tie).

      package Foo; use strict; use Hash::Util qw( lock_keys ); my @attrs = qw( name alias race ); sub new { my $class = shift; my %args = @_; my $self = bless {}, $class; lock_keys(%$self, @attrs); foreach my $k ( @attrs ) { if ( exists $args{$k} ) { $self->{$k} = $args{$k}; } } return $self; } package main; my $c = Foo->new(name => 'Aragorn', alias => 'Strider', race => 'Human +'); print "name: $c->{name}\n"; print "job: $c->{job}\n";
      output:
      $ perl test.pl name: Aragorn Attempt to access disallowed key 'job' in a restricted hash at test.pl + line 26.
      As it happens, fields in 5.10 is implemented using Hash::Utils' restriction mechanism.
        You cannot check all hash accesses at compile time. Therefore, fields must do many things at runtime. Therefore, it must have a runtime component. I suggested using tie. lock_keys() is a perfectly good other solution. tie has the added benefit of being able to do other things than just restricting keynames. YMMV.

        My criteria for good software:
        1. Does it work?
        2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?