traveler has asked for the wisdom of the Perl Monks concerning the following question:

The fields pragma seems to be valuable, useful, etc. I seldom see it in code, though. When I read this, I see that it uses pseudo-hashes. But the pseudo-hashes page says that they're "an experimental feature".

So, should I use fields when I create new o-o code? If so, should all member variables be fields?

--traveler

Replies are listed 'Best First'.
Re: (When) Should I 'use fields;'?
by pg (Canon) on Dec 23, 2002 at 21:59 UTC
    I like this feature, actually it does make me feel that Perl's OO feature is one step more mature. But ...

    One of the functionality, which this 'use fields' feature is supposed to deliver is, to do "a compile time class fields verify". It does delivered this as I will demo, but after a little bit study, I quickly came up a way to demo how this thing is hacked, and how you can cause some inconsistancy.

    I have a class defined in Package:
    package Package1; use fields qw(attr1 attr2 attr3); sub new { my Package1 $self = shift; $self = fields::new($self) unless ref $self; $self->{attr1} = "init_1"; $self->{attr2} = "init_2"; $self->{attr3} = "init_3"; return $self; } 1;
    Then I made this little test1.pl:
    use Package1; use Data::Dumper; my Package1 $p = Package1->new; $p->{attr1} = "set_1"; print $p->{attr1}, "\n"; $p->{attr4} = "set_4"; #this should fail, and did fail
    This script failed, complaining there is no field attr4 in the pseudo hash, which is good. Now the next test ...test2.pl:
    use Package1; use Data::Dumper; my Package1 $p = Package1->new; $p->[0]->{attr4} = 4; $p->[$p->[0]->{attr4}] = "set_4"; print $p->[0]->{attr4};#the above two steps sunccessfully modified the + internal pseudo hash print Dumper($p);#again proves that I successfully modified the intern +al pseudo hash #print $p->{attr4};#this fails
    For this second test case, if I uncomment the last print statement, if complains that there is no attr4 in the pseudo hash, although I actually added attr4 already, as you can see in the Data Dumper. On one hand this is good, the checking is still working under ONE definition, (the checking is based on the list I provided in the use field statement). On the other hand, this is really bad, as the data consistancy is now broken. To me, it is crystal clear that, you either make sure that I can not touch the pseudo hash at all, or if you let me touch it, then better make it looks the same from both inside and outside.

    I know this is the best they can do on top of the current foundation, but this obviously is something must be improved in the future, maybe in Perl 6.0, after the foundation is re-established.

    Hope we will have less HACKED feature in the coming days.
      How far do you want to go to limit unauthorized access to the internals? Without even const or public/private stuff like C++, the stated policy is to not provide that kind of compile-time checking but to let everyone play nice. There is always raw pointers and Devel::Peek, if it comes to that.

      In general, you need to publish and stick to a well-defined interface. If someone goes around that, then all bets are off.

      Personally, I want checking like we get with variables and "use strict". But since that's for my own benifit, not to prevent dirty tricks, it's acceptible to have away around it as long as it's not something that's easily done by accident.

Re: (When) Should I 'use fields;'?
by Hrunting (Pilgrim) on Dec 23, 2002 at 19:34 UTC
    If you use pseudo-hash-based objects, then yes, use fields is a good idea. However, pseudo-hashes are generally regarded as a good idea poorly implemented and their use is discouraged (at least, that's the impression I've gotten). I've done pseudo-hash-based classes before. It's nothing to write home about. I'd say you should skip it.
      Do note that as opposed to the current pseudohashes themselves, the fields pragma is there to stay and not going to be deprecated anytime soon.

      Makeshifts last the longest.

Re: (When) Should I 'use fields;'?
by jdporter (Paladin) on Dec 23, 2002 at 19:06 UTC
Re: (When) Should I 'use fields;'?
by John M. Dlugosz (Monsignor) on Dec 24, 2002 at 02:45 UTC
    According to the Perl 5.8 delta,
    The current user-visible implementation of pseudo-hashes (the weird use of the first array element) is deprecated starting from Perl 5.8.0 and will be removed in Perl 5.10.0, and the feature will be implemented differently. Not only is the current interface rather ugly, but the current implementation slows down normal array and hash use quite noticeably. The fields pragma interface will remain available. The restricted hashes interface is expected to be the replacement interface (see Hash::Util). If your existing programs depends on the underlying implementation, consider using Class::PseudoHash from CPAN.