FAQ
If I try to bless a restricted hash, I get:

Modification of a read-only value attempted at ext/Storable/t/restrict.t line 79.


I guess that this is a side effect of the implementation, but is it a good
thing?

Presumably we should document it as a feature.

Nicholas Clark

PS plum (my usual machine) down for a relocation. You may try CCing me here,
but the incoming MTA is very very fussy, so it's probbaly a bad idea.

Search Discussions

  • Michael G Schwern at Apr 10, 2002 at 9:14 pm

    On Wed, Apr 10, 2002 at 08:27:48PM +0100, Nicholas Clark wrote:
    If I try to bless a restricted hash, I get:

    Modification of a read-only value attempted at ext/Storable/t/restrict.t line 79.


    I guess that this is a side effect of the implementation, but is it a good
    thing?
    (having only pondered it for 30 seconds) Yes.
    Presumably we should document it as a feature.
    Yes.


    --

    Michael G. Schwern <schwern@pobox.com> http://www.pobox.com/~schwern/
    Perl Quality Assurance <perl-qa@perl.org> Kwalitee Is Job One
    My beverage utensil experiences a volume crisis.
  • Nick Ing-Simmons at Apr 11, 2002 at 7:36 am

    Nicholas Clark writes:
    If I try to bless a restricted hash, I get:

    Modification of a read-only value attempted at ext/Storable/t/restrict.t line 79.


    I guess that this is a side effect of the implementation, Yes.
    but is it a good
    thing?
    Not sure. For simple "struct" objects blessing them then restricting them
    seems natural - until you want to inherit from them.
    Presumably we should document it as a feature.

    Nicholas Clark

    PS plum (my usual machine) down for a relocation. You may try CCing me here,
    but the incoming MTA is very very fussy, so it's probbaly a bad idea.
    --
    Nick Ing-Simmons
    http://www.ni-s.u-net.com/
  • Michael G Schwern at Apr 11, 2002 at 5:39 pm

    On Thu, Apr 11, 2002 at 08:35:20AM +0100, Nick Ing-Simmons wrote:
    but is it a good thing?
    Not sure. For simple "struct" objects blessing them then restricting them
    seems natural - until you want to inherit from them.
    Inherit from a restricted hash? Wha?


    --

    Michael G. Schwern <schwern@pobox.com> http://www.pobox.com/~schwern/
    Perl Quality Assurance <perl-qa@perl.org> Kwalitee Is Job One
    They had applied the blinders of steam-grilled hamburgers to my eyes.
  • Nick Ing-Simmons at Apr 11, 2002 at 7:16 pm

    Michael G Schwern writes:
    On Thu, Apr 11, 2002 at 08:35:20AM +0100, Nick Ing-Simmons wrote:
    but is it a good thing?
    Not sure. For simple "struct" objects blessing them then restricting them
    seems natural - until you want to inherit from them.
    Inherit from a restricted hash? Wha?
    I meant an object represented at a blessed reference to a hash,
    then "restrict" the hash to stop folk messing with/adding non-allowed
    "fields".


    --
    Nick Ing-Simmons
    http://www.ni-s.u-net.com/
  • Michael G Schwern at Apr 11, 2002 at 7:52 pm

    On Thu, Apr 11, 2002 at 08:15:15PM +0100, Nick Ing-Simmons wrote:
    Michael G Schwern <schwern@pobox.com> writes:
    On Thu, Apr 11, 2002 at 08:35:20AM +0100, Nick Ing-Simmons wrote:
    but is it a good thing?
    Not sure. For simple "struct" objects blessing them then restricting them
    seems natural - until you want to inherit from them.
    Inherit from a restricted hash? Wha?
    I meant an object represented at a blessed reference to a hash,
    then "restrict" the hash to stop folk messing with/adding non-allowed
    "fields".
    Ok. Where's reblessing come in?

    I'm confused.


    --

    Michael G. Schwern <schwern@pobox.com> http://www.pobox.com/~schwern/
    Perl Quality Assurance <perl-qa@perl.org> Kwalitee Is Job One
    <purl> Hey, Schwern! THERE IS A HUGE GAZORGANSPLATTEDFARTMONGERING-
    LIGHTENINGBEASTASAURSOPOD BEHIND YOU! RUN, BEFORE IT GAFLUMMOXES YOUR
    INNARDLYBITS!
  • Nick Ing-Simmons at Apr 12, 2002 at 8:16 am

    Michael G Schwern writes:
    On Thu, Apr 11, 2002 at 08:15:15PM +0100, Nick Ing-Simmons wrote:
    I meant an object represented at a blessed reference to a hash,
    then "restrict" the hash to stop folk messing with/adding non-allowed
    "fields".
    Ok. Where's reblessing come in?
    It doesn't ;-) -
    I'm confused.
    I am waffling about stuff I have not tried - so I am not surprised.

    The issue I think I see is if base class blesses and then restricts,
    then derived class using inherited "new" sees a restricted object,
    so cannot add any keys of its own - compare the old use fields stuff.

    --
    Nick Ing-Simmons
    http://www.ni-s.u-net.com/
  • Michael G Schwern at Apr 12, 2002 at 2:08 pm

    On Fri, Apr 12, 2002 at 09:14:38AM +0100, Nick Ing-Simmons wrote:
    The issue I think I see is if base class blesses and then restricts,
    then derived class using inherited "new" sees a restricted object,
    so cannot add any keys of its own - compare the old use fields stuff.
    Oh, that. "use fields" will be rewritten to support restricted hashes
    instead of pseudo-hashes.


    --

    Michael G. Schwern <schwern@pobox.com> http://www.pobox.com/~schwern/
    Perl Quality Assurance <perl-qa@perl.org> Kwalitee Is Job One
    "what am I supposed
    to be doing at this page?"
    bend over, sonny.
    -- stimps
  • Nicholas Clark at Apr 12, 2002 at 7:54 pm

    On Fri, Apr 12, 2002 at 09:14:38AM +0100, Nick Ing-Simmons wrote:
    The issue I think I see is if base class blesses and then restricts,
    then derived class using inherited "new" sees a restricted object,
    so cannot add any keys of its own - compare the old use fields stuff.
    That's probably a better issue than the real reasons that prompted me to
    send the message, both of which are much more prosaic.

    I like writing constructors that look like this:

    sub new {
    my $self = ...

    do stuff

    return bless ($self, $class);
    }

    Problem 1: I can't do this:

    use strict;
    package Person;

    use Hash::Util qw(lock_keys);

    sub new {
    my $proto = shift;
    my $class = ref($proto) || $proto;
    my $self = {};
    $self->{NAME} = undef;
    $self->{AGE} = undef;
    $self->{PEERS} = [];

    lock_keys %$self;

    return bless ($self, $class);
    }

    package main;

    my $Guido = Person->new;

    printf "\$Guido is a %s\n", ref $Guido;
    __END__

    Problem 2:

    ../perl -Ilib restrict.pl
    Modification of a read-only value attempted at restrict.pl line 16.

    er, yes, that's such a helpful error message.
    It doesn't mention anything about restricted hashes.



    Unrelated problem 3. Should the allowed keys be carried through
    an unlock, lock cycle?

    use strict;
    use Hash::Util qw(lock_keys unlock_keys);

    my %foo;

    lock_keys %foo, 'bonus';

    printf "There are %d keys\n", scalar keys %foo;

    unlock_keys %foo;

    printf "There are still %d keys\n", scalar keys %foo;

    lock_keys %foo;

    printf "There are still %d keys\n", scalar keys %foo;

    # Should we be able to do this? We've just locked it again, but didn't specify
    # any extra keys.

    $foo{bonus} = 1;

    printf "There is %d key\n", scalar keys %foo;

    # This fails

    $foo{"the end"} = 1;
    __END__

    Nicholas Clark
    --
    Even better than the real thing: http://nms-cgi.sourceforge.net/
  • Michael G Schwern at Apr 12, 2002 at 9:13 pm

    On Fri, Apr 12, 2002 at 08:52:42PM +0100, Nicholas Clark wrote:
    Problem 1: I can't do this:

    use strict;
    package Person;

    use Hash::Util qw(lock_keys);

    sub new {
    my $proto = shift;
    my $class = ref($proto) || $proto;
    my $self = {};
    $self->{NAME} = undef;
    $self->{AGE} = undef;
    $self->{PEERS} = [];

    lock_keys %$self;

    return bless ($self, $class);
    }
    Solution: Avoid the problem.

    sub new {
    my $proto = shift;
    my $class = ref($proto) || $proto;

    my $self = bless {}, $class;
    $self->{NAME} = undef;
    $self->{AGE} = undef;
    $self->{PEERS} = [];

    lock_keys %$self;

    return $self;
    }

    Unrelated problem 3. Should the allowed keys be carried through
    an unlock, lock cycle?
    I can't think of where we'd store the set of previously locked keys
    once you've unlocked the hash without adding on extra internal data
    structures, which we're strenuously avoiding.


    --

    Michael G. Schwern <schwern@pobox.com> http://www.pobox.com/~schwern/
    Perl Quality Assurance <perl-qa@perl.org> Kwalitee Is Job One
    HA HA HA You're all so ridiculous! But thanks for the money!
  • Nicholas Clark at Apr 12, 2002 at 9:39 pm

    On Fri, Apr 12, 2002 at 05:12:56PM -0400, Michael G Schwern wrote:
    On Fri, Apr 12, 2002 at 08:52:42PM +0100, Nicholas Clark wrote:
    Problem 1: I can't do this:
    Solution: Avoid the problem.
    I know that that's the Solution. I was just whining that I had to make
    effort avoid the problem. Avoiding something is non-lazy, and I'm told
    that laziness is a virtue. :-)
    Unrelated problem 3. Should the allowed keys be carried through
    an unlock, lock cycle?
    I can't think of where we'd store the set of previously locked keys
    once you've unlocked the hash without adding on extra internal data
    structures, which we're strenuously avoiding.
    Whoa.

    We *are* keeping the set previously locked keys currently.
    I think that this is bad (well, if it's a feature lets document it)
    because there is no way to clean them out short of a brute force hash copy.
    Which is expensive.

    Or did I misunderstand you?

    Nicholas Clark
  • Michael G Schwern at Apr 12, 2002 at 9:57 pm

    On Fri, Apr 12, 2002 at 10:39:49PM +0100, Nicholas Clark wrote:
    Unrelated problem 3. Should the allowed keys be carried through
    an unlock, lock cycle?
    I can't think of where we'd store the set of previously locked keys
    once you've unlocked the hash without adding on extra internal data
    structures, which we're strenuously avoiding.
    Whoa.

    We *are* keeping the set previously locked keys currently.
    Oh, right! I'm wrong.
    I think that this is bad (well, if it's a feature lets document it)
    Not a feature.
    because there is no way to clean them out short of a brute force hash copy.
    Which is expensive.
    You can write a little XS function to clean them out and have it be
    called by unlock_keys(). Or not. Depends on if the locked keys
    should be carried over between unlocks.

    Of course, Jarkko will not like new XS.
    Or did I misunderstand you?
    No, I'm unthinking.


    The only other reason I don't like the idea of holding over previously
    locked key sets between unlocks is just from an interface &
    documentation complication standpoint. lock_keys() will be:

    "locks the current keyset, or if you've previously unlocked this
    hash it will lock the last locked keyset"

    which is a bit to think about.


    Split the interface. Hash::Util functions are just little wrapper
    functions. Write some new wrapper functions.


    --

    Michael G. Schwern <schwern@pobox.com> http://www.pobox.com/~schwern/
    Perl Quality Assurance <perl-qa@perl.org> Kwalitee Is Job One
    <purl> Hey Schwern! honk, honk, honk, honk, honk, honk, honk, honk,
    honk, honk, honk, honk, honk, honk, honk, honk, honk, honk, honk,
    honk, honk, honk, honk, honk, honk, honk, honk, honk, honk, honk,
    honk, honk, honk, honk, honk, honk, honk, honk, honk, honk, honk,
    honk, honk, honk, honk, honk, honk, honk, honk, honk, honk!
  • Jarkko Hietaniemi at Apr 12, 2002 at 10:34 pm

    On Fri, Apr 12, 2002 at 05:56:53PM -0400, Michael G Schwern wrote:
    On Fri, Apr 12, 2002 at 10:39:49PM +0100, Nicholas Clark wrote:
    Unrelated problem 3. Should the allowed keys be carried through
    an unlock, lock cycle?
    I can't think of where we'd store the set of previously locked keys
    once you've unlocked the hash without adding on extra internal data
    structures, which we're strenuously avoiding.
    Whoa.

    We *are* keeping the set previously locked keys currently.
    Oh, right! I'm wrong.
    I think that this is bad (well, if it's a feature lets document it)
    Not a feature.
    because there is no way to clean them out short of a brute force hash copy.
    Which is expensive.
    You can write a little XS function to clean them out and have it be
    called by unlock_keys(). Or not. Depends on if the locked keys
    should be carried over between unlocks.

    Of course, Jarkko will not like new XS.
    If it's just a new function within an existing XS file and the just
    described behaviour makes sense (I didn't follow the reasoning too
    closely), it's not that bad. It's completely new XS extensions that
    make my skin crawl. Well, did make my skin crawl: at this point, it
    would make my skin leap and bound.

    --
    $jhi++; # http://www.iki.fi/jhi/
    # There is this special biologist word we use for 'stable'.
    # It is 'dead'. -- Jack Cohen
  • Nicholas Clark at Apr 13, 2002 at 10:47 pm

    On Sat, Apr 13, 2002 at 01:34:37AM +0300, Jarkko Hietaniemi wrote:
    On Fri, Apr 12, 2002 at 05:56:53PM -0400, Michael G Schwern wrote:
    On Fri, Apr 12, 2002 at 10:39:49PM +0100, Nicholas Clark wrote:
    Unrelated problem 3. Should the allowed keys be carried through
    an unlock, lock cycle?
    I can't think of where we'd store the set of previously locked keys
    once you've unlocked the hash without adding on extra internal data
    structures, which we're strenuously avoiding.
    Whoa.

    We *are* keeping the set previously locked keys currently.
    Oh, right! I'm wrong.
    I think that this is bad (well, if it's a feature lets document it)
    Not a feature.
    because there is no way to clean them out short of a brute force hash copy.
    Which is expensive.
    You can write a little XS function to clean them out and have it be
    called by unlock_keys(). Or not. Depends on if the locked keys
    should be carried over between unlocks.
    I suspect it's more lazy to defer calling it until lock_keys is called again,
    as placeholders seem to cause no harm inside a regular hash.
    And as a hash holds a count of placeholders one can also make the iteration
    conditional on the hash having placeholders.
    Of course, Jarkko will not like new XS.
    If it's just a new function within an existing XS file and the just
    described behaviour makes sense (I didn't follow the reasoning too
    closely), it's not that bad. It's completely new XS extensions that
    make my skin crawl. Well, did make my skin crawl: at this point, it
    would make my skin leap and bound.
    Hopefully then the appended is deemed acceptable.
    Except that it needs a better name than

    Internals::hv_clear_placeholders


    On an unrelated issue, lock_keys does this:


    sub lock_keys (\%;@) {
    my($hash, @keys) = @_;

    ...

    return undef;
    }


    Why the return undef?
    Surely return; is better, as it gives () in list context, undef in scalar.

    Nicholas Clark
    --
    Even better than the real thing: http://nms-cgi.sourceforge.net/

    --- lib/Hash/Util.t.orig Sat Apr 6 18:12:26 2002
    +++ lib/Hash/Util.t Sat Apr 13 22:29:18 2002
    @@ -6,7 +6,7 @@
    chdir 't';
    }
    }
    -use Test::More tests => 45;
    +use Test::More tests => 55;

    my @Exported_Funcs;
    BEGIN {
    @@ -168,3 +168,38 @@
    lock_keys(%ENV);
    eval { () = $ENV{I_DONT_EXIST} };
    like( $@, qr/^Attempt to access disallowed key 'I_DONT_EXIST' in a restricted hash/, 'locked %ENV');
    +
    +{
    + my %hash;
    +
    + lock_keys(%hash, 'first');
    +
    + is (scalar keys %hash, 0, "place holder isn't a key");
    + $hash{first} = 1;
    + is (scalar keys %hash, 1, "we now have a key");
    + delete $hash{first};
    + is (scalar keys %hash, 0, "now no key");
    +
    + unlock_keys(%hash);
    +
    + $hash{interregnum} = 1.5;
    + is (scalar keys %hash, 1, "key again");
    + delete $hash{interregnum};
    + is (scalar keys %hash, 0, "no key again");
    +
    + lock_keys(%hash, 'second');
    +
    + is (scalar keys %hash, 0, "place holder isn't a key");
    +
    + eval {$hash{zeroeth} = 0};
    + like ($@,
    + qr/^Attempt to access disallowed key 'zeroeth' in a restricted hash/,
    + 'locked key never mentioned before should fail');
    + eval {$hash{first} = -1};
    + like ($@,
    + qr/^Attempt to access disallowed key 'first' in a restricted hash/,
    + 'previously locked place holders should also fail');
    + is (scalar keys %hash, 0, "and therefore there are no keys");
    + $hash{second} = 1;
    + is (scalar keys %hash, 1, "we now have just one key");
    +}
    --- lib/Hash/Util.pm.orig Tue Mar 12 17:48:57 2002
    +++ lib/Hash/Util.pm Sat Apr 13 23:03:45 2002
    @@ -71,6 +71,7 @@
    sub lock_keys (\%;@) {
    my($hash, @keys) = @_;

    + Internals::hv_clear_placeholders %$hash;
    if( @keys ) {
    my %keys = map { ($_ => 1) } @keys;
    my %original_keys = map { ($_ => 1) } keys %$hash;
    --- universal.c.orig Tue Mar 12 21:49:15 2002
    +++ universal.c Sat Apr 13 23:04:07 2002
    @@ -169,6 +169,7 @@
    XS(XS_utf8_native_to_unicode);
    XS(XS_Internals_SvREADONLY);
    XS(XS_Internals_SvREFCNT);
    +XS(XS_Internals_hv_clear_placeholders);

    void
    Perl_boot_core_UNIVERSAL(pTHX)
    @@ -187,6 +188,8 @@
    newXS("utf8::unicode_to_native", XS_utf8_unicode_to_native, file);
    newXSproto("Internals::SvREADONLY",XS_Internals_SvREADONLY, file, "\\[$%@];$");
    newXSproto("Internals::SvREFCNT",XS_Internals_SvREFCNT, file, "\\[$%@];$");
    + newXSproto("Internals::hv_clear_placeholders",
    + XS_Internals_hv_clear_placeholders, file, "\\%");
    }


    @@ -500,3 +503,45 @@
    XSRETURN_UNDEF; /* Can't happen. */
    }

    +/* Maybe this should return the number of placeholders found in scalar context,
    + and a list of them in list context. */
    +XS(XS_Internals_hv_clear_placeholders)
    +{
    + dXSARGS;
    + HV *hv = (HV *) SvRV(ST(0));
    +
    + /* I don't care how many parameters were passed in, but I want to avoid
    + the unused variable warning. */
    +
    + items = HvPLACEHOLDERS(hv);
    +
    + if (items) {
    + HE *entry;
    + I32 riter = HvRITER(hv);
    + HE *eiter = HvEITER(hv);
    + hv_iterinit(hv);
    + while (items
    + && (entry
    + = hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS))) {
    + SV *val = hv_iterval(hv, entry);
    +
    + if (val == &PL_sv_undef) {
    +
    + /* It seems that I have to go back in the front of the hash
    + API to delete a hash, even though I have a HE structure
    + pointing to the very entry I want to delete, and could hold
    + onto the previous HE that points to it. And it's easier to
    + go in with SVs as I can then specify the precomputed hash,
    + and don't have fun and games with utf8 keys. */
    + SV *key = hv_iterkeysv(entry);
    +
    + hv_delete_ent (hv, key, G_DISCARD, HeHASH(entry));
    + items--;
    + }
    + }
    + HvRITER(hv) = riter;
    + HvEITER(hv) = eiter;
    + }
    +
    + XSRETURN(0);
    +}
  • Jarkko Hietaniemi at Apr 13, 2002 at 10:56 pm
    Please remind me again why did this have to be an XS function instead
    of an hv.c function....?

    --
    $jhi++; # http://www.iki.fi/jhi/
    # There is this special biologist word we use for 'stable'.
    # It is 'dead'. -- Jack Cohen
  • Jarkko Hietaniemi at Apr 13, 2002 at 11:05 pm

    On Sun, Apr 14, 2002 at 01:55:58AM +0300, Jarkko Hietaniemi wrote:
    Please remind me again why did this have to be an XS function instead
    of an hv.c function....?
    Ahhh, okay, because Hash/Util.pm wants to call it. Ummm. Maybe I do
    dislike the idea, after all. Or at least the function needs (as you
    said) a much better name. It seems so very strange to have a single
    function for hash ops in XS, when all the rest are in hv.c.

    --
    $jhi++; # http://www.iki.fi/jhi/
    # There is this special biologist word we use for 'stable'.
    # It is 'dead'. -- Jack Cohen
  • Jarkko Hietaniemi at Apr 13, 2002 at 11:08 pm

    On Sun, Apr 14, 2002 at 02:05:51AM +0300, Jarkko Hietaniemi wrote:
    On Sun, Apr 14, 2002 at 01:55:58AM +0300, Jarkko Hietaniemi wrote:
    Please remind me again why did this have to be an XS function instead
    of an hv.c function....?
    Ahhh, okay, because Hash/Util.pm wants to call it. Ummm. Maybe I do
    dislike the idea, after all. Or at least the function needs (as you
    said) a much better name. It seems so very strange to have a single
    function for hash ops in XS, when all the rest are in hv.c.
    .... that is, if one counts universal.c as "XS".

    --
    $jhi++; # http://www.iki.fi/jhi/
    # There is this special biologist word we use for 'stable'.
    # It is 'dead'. -- Jack Cohen
  • Nicholas Clark at Apr 14, 2002 at 8:21 pm

    On Sun, Apr 14, 2002 at 02:05:51AM +0300, Jarkko Hietaniemi wrote:
    On Sun, Apr 14, 2002 at 01:55:58AM +0300, Jarkko Hietaniemi wrote:
    Please remind me again why did this have to be an XS function instead
    of an hv.c function....?
    I thought this too
    Ahhh, okay, because Hash/Util.pm wants to call it. Ummm. Maybe I do
    dislike the idea, after all. Or at least the function needs (as you
    said) a much better name. It seems so very strange to have a single
    function for hash ops in XS, when all the rest are in hv.c.
    I'm quite happy with the idea of the main function being in hv.c, but
    there would need to be an XS wrapper somewhere so that Hash/Util.pm can
    call it.

    Nicholas Clark
    --
    Even better than the real thing: http://nms-cgi.sourceforge.net/
  • Michael G Schwern at Apr 14, 2002 at 1:06 am

    On Sat, Apr 13, 2002 at 11:43:02PM +0100, Nicholas Clark wrote:
    On an unrelated issue, lock_keys does this:


    sub lock_keys (\%;@) {
    my($hash, @keys) = @_;

    ...

    return undef;
    }


    Why the return undef?
    Surely return; is better, as it gives () in list context, undef in scalar.
    Doesn't make a difference, it could return "Basset Hounds got long
    ears". The return value of lock_keys() means nothing.


    --

    Michael G. Schwern <schwern@pobox.com> http://www.pobox.com/~schwern/
    Perl Quality Assurance <perl-qa@perl.org> Kwalitee Is Job One
    Monkey tennis
  • Nicholas Clark at Apr 14, 2002 at 8:21 pm

    On Sat, Apr 13, 2002 at 09:06:10PM -0400, Michael G Schwern wrote:
    On Sat, Apr 13, 2002 at 11:43:02PM +0100, Nicholas Clark wrote:
    On an unrelated issue, lock_keys does this:


    sub lock_keys (\%;@) {
    my($hash, @keys) = @_;

    ...

    return undef;
    }


    Why the return undef?
    Surely return; is better, as it gives () in list context, undef in scalar.
    Doesn't make a difference, it could return "Basset Hounds got long
    ears". The return value of lock_keys() means nothing.
    Not sure whom I'm implicitly criticising here, but I always viewed
    C<return undef;> as bad style for a function that is returning false and has
    no specific need to return a single undef, as it maps into truth in list
    context. Sufficient that I feel that C<return undef;> is bad design.

    return;

    does the right thing in both scalar and list context, and I'd like to
    promote what I feel is good design in the core code. Similar to a certain
    CGI library being the epitome of beginners mistakes and other poor practice,
    which in turn gives perl a bad reputation.

    Something which >>>> http://nms-cgi.sourceforge.net/ <<<< this one is trying
    to correct.

    Holy war will now ensue.

    Nicholas Clark

    PS Yes, I have been drinking from the same beer kitty as Dave Cross.
    --
    Even better than the real thing: http://nms-cgi.sourceforge.net/
  • Michael G Schwern at Apr 15, 2002 at 1:27 pm

    On Sun, Apr 14, 2002 at 08:09:11PM +0100, Nicholas Clark wrote:
    Doesn't make a difference, it could return "Basset Hounds got long
    ears". The return value of lock_keys() means nothing.
    Not sure whom I'm implicitly criticising here, but I always viewed
    C<return undef;> as bad style for a function that is returning false and has
    no specific need to return a single undef, as it maps into truth in list
    context.
    <snip>

    Yes, I agree with you.

    However, since the return value of lock_keys() is unused it's all
    moot. Could return true, could return false, could return an empty
    list, could return the 121st page of your local phone book. Doesn't
    matter, you're not supposed to be using it. Change it to whatever you
    like.


    I've experimented with having functions poison their return value with
    tied scalars that when FETCH'd cause a warning or error, but there are
    too many places where an implicit fetch happens.


    --

    Michael G. Schwern <schwern@pobox.com> http://www.pobox.com/~schwern/
    Perl Quality Assurance <perl-qa@perl.org> Kwalitee Is Job One
    There is nothing here
    But a lip of hardened paste
    From our night of joy.
    -- ignatz
  • Jarkko Hietaniemi at Apr 15, 2002 at 1:55 pm

    On Mon, Apr 15, 2002 at 09:26:56AM -0400, Michael G Schwern wrote:
    On Sun, Apr 14, 2002 at 08:09:11PM +0100, Nicholas Clark wrote:
    Doesn't make a difference, it could return "Basset Hounds got long
    ears". The return value of lock_keys() means nothing.
    Not sure whom I'm implicitly criticising here, but I always viewed
    C<return undef;> as bad style for a function that is returning false and has
    no specific need to return a single undef, as it maps into truth in list
    context.
    <snip>

    Yes, I agree with you.

    However, since the return value of lock_keys() is unused it's all
    moot. Could return true, could return false, could return an empty
    list, could return the 121st page of your local phone book. Doesn't
    matter, you're not supposed to be using it. Change it to whatever you
    like.
    Oh, stop being silly. People not supposed to be using a return value
    is not a reason to write questionable code.
    I've experimented with having functions poison their return value with
    tied scalars that when FETCH'd cause a warning or error, but there are
    too many places where an implicit fetch happens.


    --

    Michael G. Schwern <schwern@pobox.com> http://www.pobox.com/~schwern/
    Perl Quality Assurance <perl-qa@perl.org> Kwalitee Is Job One
    There is nothing here
    But a lip of hardened paste
    From our night of joy.
    -- ignatz
    --
    $jhi++; # http://www.iki.fi/jhi/
    # There is this special biologist word we use for 'stable'.
    # It is 'dead'. -- Jack Cohen
  • Nicholas Clark at Apr 14, 2002 at 9:56 pm
    Slight improvement to the tests, which tries to stop a possible subtle
    implementation bug. (There is no bug, but this stops some other bugger
    introducing it in the future)

    Nicholas Clark
    --
    Even better than the real thing: http://nms-cgi.sourceforge.net/

    --- lib/Hash/Util.t.orig Sun Apr 14 17:25:08 2002
    +++ lib/Hash/Util.t Sun Apr 14 22:50:55 2002
    @@ -6,7 +6,8 @@
    chdir 't';
    }
    }
    -use Test::More tests => 55;
    +use Test::More tests => 61;
    +use strict;

    my @Exported_Funcs;
    BEGIN {
    @@ -202,4 +203,27 @@
    is (scalar keys %hash, 0, "and therefore there are no keys");
    $hash{second} = 1;
    is (scalar keys %hash, 1, "we now have just one key");
    + delete $hash{second};
    + is (scalar keys %hash, 0, "back to zero");
    +
    + unlock_keys(%hash); # We have deliberately left a placeholder.
    +
    + $hash{void} = undef;
    + $hash{nowt} = undef;
    +
    + is (scalar keys %hash, 2, "two keys, values both undef");
    +
    + lock_keys(%hash);
    +
    + is (scalar keys %hash, 2, "still two keys after locking");
    +
    + eval {$hash{second} = -1};
    + like ($@,
    + qr/^Attempt to access disallowed key 'second' in a restricted hash/,
    + 'previously locked place holders should fail');
    +
    + is ($hash{void}, undef,
    + "undef values should not be misunderstood as placeholders");
    + is ($hash{nowt}, undef,
    + "undef values should not be misunderstood as placeholders (again)");
    }
  • Jim Cromie at Apr 11, 2002 at 8:09 pm

    Nick Ing-Simmons wrote:
    Michael G Schwern <schwern@pobox.com> writes:
    On Thu, Apr 11, 2002 at 08:35:20AM +0100, Nick Ing-Simmons wrote:

    but is it a good thing?
    Not sure. For simple "struct" objects blessing them then restricting them
    seems natural - until you want to inherit from them.
    Inherit from a restricted hash? Wha?
    I meant an object represented at a blessed reference to a hash,
    then "restrict" the hash to stop folk messing with/adding non-allowed
    "fields".
    sounds like java's final keyword..

    in 5.9, it would be nice to have it both ways;
    restrict hash sometime after construction, (allowing C++ish copy
    constructor)
    but b4 actual use.

    Im assuming C++ ish situation where constructor init statements
    can do stuff that in-ctor-body code cannot.

    maybe automatic restrict on 1st method-dereference.
  • Michael G Schwern at Apr 11, 2002 at 8:17 pm

    On Thu, Apr 11, 2002 at 02:09:20PM -0600, Jim Cromie wrote:
    sounds like java's final keyword..
    No, this is completely different. See Hash::Util in bleadperl.


    --

    Michael G. Schwern <schwern@pobox.com> http://www.pobox.com/~schwern/
    Perl Quality Assurance <perl-qa@perl.org> Kwalitee Is Job One
    Please Captain, not in front of the Klingons.
  • Jim Cromie at Apr 11, 2002 at 9:04 pm

    Michael G Schwern wrote:
    On Thu, Apr 11, 2002 at 02:09:20PM -0600, Jim Cromie wrote:

    sounds like java's final keyword..
    No, this is completely different. See Hash::Util in bleadperl.
    Theyre different, but similar... (in terms of controlling / disallowing
    subclassing )
    esp wrt living-room/shotgun philosophy.

    lock-keys will prevent a sub-class from extending the hash.
    while this doesnt prevent method-overrides like final does,
    it does stop (well, slow down) a mis-guided attempt at sub-classing.

    package A;

    sub new {
    my $me = bless { %proto }, shift;
    lock_keys(%$me);
    }

    package B;

    sub new {
    my $newme = B->SUPER::new();
    unlock_keys(%$newme);

    $newme->{newkey} = 'yada';
    bless $newme, shift;
    lock_keys(%$newme);
    }

    is possible, if unwize. and since unlock_keys is there, subclass can do
    it w/o
    permission from superclass.

    Shotgun? I dont need no stinking shotgun. :-)
  • Jarkko Hietaniemi at Apr 11, 2002 at 9:07 pm

    package A;

    sub new {
    my $me = bless { %proto }, shift;
    lock_keys(%$me);
    }

    package B;

    sub new {
    my $newme = B->SUPER::new();
    unlock_keys(%$newme);

    $newme->{newkey} = 'yada';
    bless $newme, shift;
    lock_keys(%$newme);
    }

    is possible, if unwize. and since unlock_keys is there, subclass can do
    it w/o permission from superclass.
    Yikes. We can try locking the door but some with a bulldozer wil win.

    --
    $jhi++; # http://www.iki.fi/jhi/
    # There is this special biologist word we use for 'stable'.
    # It is 'dead'. -- Jack Cohen
  • Tim Bunce at Apr 12, 2002 at 9:37 am

    On Thu, Apr 11, 2002 at 03:04:06PM -0600, Jim Cromie wrote:

    package A;

    sub new {
    my $me = bless { %proto }, shift;
    lock_keys(%$me);
    }

    package B;

    sub new {
    my $newme = B->SUPER::new();
    unlock_keys(%$newme);
    $newme->{newkey} = 'yada';
    bless $newme, shift;
    lock_keys(%$newme);
    }

    is possible, if unwize. and since unlock_keys is there, subclass can do
    it w/o permission from superclass.
    Of course, A::new() should be written to accept a list of extra keys.
    Shotgun? I dont need no stinking shotgun. :-)
    The way of Perl.

    And why bless again? Why not
    my $newme = shift->SUPER::new();

    Tim.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupperl5-porters @
categoriesperl
postedApr 10, '02 at 7:27p
activeApr 15, '02 at 1:55p
posts28
users8
websiteperl.org

People

Translate

site design / logo © 2022 Grokbase