RFC: UniqueID Module

Discussion in 'Perl Misc' started by John, Apr 3, 2004.

  1. John

    John Guest

    I need an alternative for 'use constant', but that allows the definition of
    unique IDs not associated with scalar values.

    I propose the UniqueID class, summarized below. I'm asking this list:

    - Is this module necessary, or is there a better way to do this?
    - Is it aptly named?
    - Other comments before I post to CPAN?


    Synopsis:

    use UniqueID qw (red yellow blue);

    my $color = red;

    print "Just as we thought!\n" if $color == red;
    print "This will never happen!\n" if $color == blue;
    print "Nor will this!\n" if $color == 'red';

    print "Color is ".$color->name.".\n";

    $color + 1; #Raises an exception. Addition isn't defined for UniqueID
    objects.

    Output:
    Just as we thought!
    Color is red.
    The '+' operation isn't defined for UniqueID objects at C:\test5.pl line 11


    Rationale:

    UniqueID lets you define unique identifiers that are not associated with
    scalar values. Contrast this with the "constant" package, which simply
    aliases names to scalar values.

    UIDs are safer than constants, because they can not accidently be confused
    with un-related scalars. For example, the following accident might happen
    using aliased constants:

    use constant red => 0;

    my $color;
    my $color = red if not 1; #*Don't* set $color to red.

    #Comparing $color to red is the same as comparing it to 0.
    if($color == red) {
    print "Color is red!\n";
    } else {
    print "Color is NOT red!\n";
    }

    Output: Color is red!

    Whereas colors can never be confused with numbers if you use UIDs:

    use UniqueID qw (red);

    my $color = red if 0; #*Don't* set $color to red.

    ###Red doesn't equal 0 or undef.
    if($color == red) {
    print "Color is red!\n";
    } else {
    print "Color is NOT red!\n";
    }

    Output: Color is NOT red!
     
    John, Apr 3, 2004
    #1
    1. Advertising

  2. John

    Anno Siegel Guest

    John <> wrote in comp.lang.perl.misc:
    > I need an alternative for 'use constant', but that allows the definition of
    > unique IDs not associated with scalar values.
    >
    > I propose the UniqueID class, summarized below. I'm asking this list:
    >
    > - Is this module necessary, or is there a better way to do this?
    > - Is it aptly named?
    > - Other comments before I post to CPAN?
    >
    >
    > Synopsis:
    >
    > use UniqueID qw (red yellow blue);
    >
    > my $color = red;
    >
    > print "Just as we thought!\n" if $color == red;
    > print "This will never happen!\n" if $color == blue;
    > print "Nor will this!\n" if $color == 'red';

    ^^
    Wrong comparison operator. "==" is for numbers, you need "eq".

    > print "Color is ".$color->name.".\n";
    >
    > $color + 1; #Raises an exception. Addition isn't defined for UniqueID
    > objects.
    >
    > Output:
    > Just as we thought!
    > Color is red.
    > The '+' operation isn't defined for UniqueID objects at C:\test5.pl line 11


    You can have unique identifiers in Perl by just taking a reference to
    anything. So you get most of the behavior you describe after just saying:

    use constant red => \ '';
    use constant yellow => \ '';
    use constant blue => \ '';

    instead of

    use UniqueID qw (red yellow blue);

    The difference is that the arithmetic operation is allowed and that
    there is no ->name method.

    > Rationale:
    >
    > UniqueID lets you define unique identifiers that are not associated with
    > scalar values. Contrast this with the "constant" package, which simply
    > aliases names to scalar values.
    >
    > UIDs are safer than constants, because they can not accidently be confused
    > with un-related scalars. For example, the following accident might happen
    > using aliased constants:
    >
    > use constant red => 0;
    >
    > my $color;
    > my $color = red if not 1; #*Don't* set $color to red.
    >
    > #Comparing $color to red is the same as comparing it to 0.
    > if($color == red) {
    > print "Color is red!\n";
    > } else {
    > print "Color is NOT red!\n";
    > }
    >
    > Output: Color is red!


    ....plus a warning, if warnings are on as they should. While an undef
    *can* be mistaken for a 0 (or a ""), there is a difference, and a
    program can tell which is which.

    [...]

    I have as yet not missed the functionality of UniqueID.

    Anno
     
    Anno Siegel, Apr 3, 2004
    #2
    1. Advertising

  3. John

    John Guest

    One more point in the case for UniqueID that I didn't mention: a UniqueID
    would maintain it's identity through serialization across processes. It
    would be implemented as a blessed reference to a scalar containing the
    symbol name.

    Also, below is another perhaps beter example of UniqueID's use, although it
    is still contrived:

    use UniqueID 'error';

    sub bar {
    my($arg) = @_;
    return not(1) ? $arg : error;
    }

    my $foo = bar('baz');
    print $foo eq error ? "Foo is no good." : "Foo is $foo.";

    The actual situation where I want to use UniqueID is too complicated for
    this post, but I need a variable to be able to contain *any* value that the
    user can throw at it, *or* some flag value that is above all the other
    values

    Also, are you sure that == and != wouldn't bet appropriate comparators,
    since UniqueID objects aren't strings any more than they are numbers, and
    the == operators implies "mathematical identity", which is really what I'm
    aiming for. So you'd have

    use UniqueID 'infinity';
    my $variable = 5;
    print "5 is infinite!\n" if $variable == infinity;



    "Anno Siegel" <-berlin.de> wrote in message
    news:c4llrr$41q$-Berlin.DE...
    > John <> wrote in comp.lang.perl.misc:
    > > I need an alternative for 'use constant', but that allows the definition

    of
    > > unique IDs not associated with scalar values.
    > >
    > > I propose the UniqueID class, summarized below. I'm asking this list:
    > >
    > > - Is this module necessary, or is there a better way to do this?
    > > - Is it aptly named?
    > > - Other comments before I post to CPAN?
    > >
    > >
    > > Synopsis:
    > >
    > > use UniqueID qw (red yellow blue);
    > >
    > > my $color = red;
    > >
    > > print "Just as we thought!\n" if $color == red;
    > > print "This will never happen!\n" if $color == blue;
    > > print "Nor will this!\n" if $color == 'red';

    > ^^
    > Wrong comparison operator. "==" is for numbers, you need "eq".
    >
    > > print "Color is ".$color->name.".\n";
    > >
    > > $color + 1; #Raises an exception. Addition isn't defined for UniqueID
    > > objects.
    > >
    > > Output:
    > > Just as we thought!
    > > Color is red.
    > > The '+' operation isn't defined for UniqueID objects at C:\test5.pl line

    11
    >
    > You can have unique identifiers in Perl by just taking a reference to
    > anything. So you get most of the behavior you describe after just saying:
    >
    > use constant red => \ '';
    > use constant yellow => \ '';
    > use constant blue => \ '';
    >
    > instead of
    >
    > use UniqueID qw (red yellow blue);
    >
    > The difference is that the arithmetic operation is allowed and that
    > there is no ->name method.
    >
    > > Rationale:
    > >
    > > UniqueID lets you define unique identifiers that are not associated with
    > > scalar values. Contrast this with the "constant" package, which simply
    > > aliases names to scalar values.
    > >
    > > UIDs are safer than constants, because they can not accidently be

    confused
    > > with un-related scalars. For example, the following accident might

    happen
    > > using aliased constants:
    > >
    > > use constant red => 0;
    > >
    > > my $color;
    > > my $color = red if not 1; #*Don't* set $color to red.
    > >
    > > #Comparing $color to red is the same as comparing it to 0.
    > > if($color == red) {
    > > print "Color is red!\n";
    > > } else {
    > > print "Color is NOT red!\n";
    > > }
    > >
    > > Output: Color is red!

    >
    > ...plus a warning, if warnings are on as they should. While an undef
    > *can* be mistaken for a 0 (or a ""), there is a difference, and a
    > program can tell which is which.
    >
    > [...]
    >
    > I have as yet not missed the functionality of UniqueID.
    >
    > Anno
     
    John, Apr 3, 2004
    #3
  4. John

    John Guest

    Re: UniqueID Module

    Here is a proposed implementation for the package:

    use strict; use warnings;
    package UniqueID;
    our $VERSION = '1.01';

    use Carp;

    use overload
    '==' => sub {my $class = ref(shift); croak "'==' operator isn't defined
    for $class objects. Did you mean 'eq'?"},
    'eq' => 'equals',
    '!=' => sub {my $class = ref(shift); croak "'!=' operator isn't defined
    for $class objects. Did you mean 'ne'?"},
    'ne' => 'notequals',
    nomethod => sub {
    my($a, $b, $c, $operator) = @_;
    my $class = ref($a);
    croak "The '$operator' operation isn't defined for $class objects";
    },
    '""' => 'stringify'
    ;

    sub stringify {
    my($self) = @_;
    return overload::StrVal($self).'='.$$self;
    }
    sub equals {
    ref($_[1]) eq ref($_[0]) and ${$_[0]} eq ${$_[1]}
    };
    sub notequals {
    not (ref($_[1]) eq ref($_[0]) and ${$_[0]} eq ${$_[1]})
    };

    sub name {
    my($self) = @_;
    my @parts = split /\:\:/, $$self;
    return $parts[-1];
    }

    sub fullname {
    my($self) = @_;
    return $$self;
    }

    sub new {
    my($pkg, $client_package, $name) = @_;

    my $string = $client_package."::".$name;
    my $self = bless \$string, $pkg;
    return $self;
    }

    sub make_identifier {
    my($pkg, $client_package, $name) = @_;

    my $id = $pkg->new($client_package, $name);

    no strict 'refs';
    *{$client_package."::".$name} = sub {
    $id;
    };
    }

    sub import {
    my($pkg, @names) = @_;
    my $client_package = caller(0);
    for(@names) {
    $pkg->make_identifier($client_package, $_);
    }
    }
    "John" <> wrote in message
    news:c4l9gc$2iqd$...
    > I need an alternative for 'use constant', but that allows the definition

    of
    > unique IDs not associated with scalar values.
    >
    > I propose the UniqueID class, summarized below. I'm asking this list:
    >
    > - Is this module necessary, or is there a better way to do this?
    > - Is it aptly named?
    > - Other comments before I post to CPAN?
    >
    >
    > Synopsis:
    >
    > use UniqueID qw (red yellow blue);
    >
    > my $color = red;
    >
    > print "Just as we thought!\n" if $color == red;
    > print "This will never happen!\n" if $color == blue;
    > print "Nor will this!\n" if $color == 'red';
    >
    > print "Color is ".$color->name.".\n";
    >
    > $color + 1; #Raises an exception. Addition isn't defined for UniqueID
    > objects.
    >
    > Output:
    > Just as we thought!
    > Color is red.
    > The '+' operation isn't defined for UniqueID objects at C:\test5.pl line

    11
    >
    >
    > Rationale:
    >
    > UniqueID lets you define unique identifiers that are not associated with
    > scalar values. Contrast this with the "constant" package, which simply
    > aliases names to scalar values.
    >
    > UIDs are safer than constants, because they can not accidently be confused
    > with un-related scalars. For example, the following accident might happen
    > using aliased constants:
    >
    > use constant red => 0;
    >
    > my $color;
    > my $color = red if not 1; #*Don't* set $color to red.
    >
    > #Comparing $color to red is the same as comparing it to 0.
    > if($color == red) {
    > print "Color is red!\n";
    > } else {
    > print "Color is NOT red!\n";
    > }
    >
    > Output: Color is red!
    >
    > Whereas colors can never be confused with numbers if you use UIDs:
    >
    > use UniqueID qw (red);
    >
    > my $color = red if 0; #*Don't* set $color to red.
    >
    > ###Red doesn't equal 0 or undef.
    > if($color == red) {
    > print "Color is red!\n";
    > } else {
    > print "Color is NOT red!\n";
    > }
    >
    > Output: Color is NOT red!
    >
    >
    >
    >
    >
     
    John, Apr 3, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Whitney
    Replies:
    1
    Views:
    606
    Natty Gur
    Jul 21, 2003
  2. Henri
    Replies:
    2
    Views:
    12,210
    Henri
    May 18, 2004
  3. Kepler
    Replies:
    1
    Views:
    453
    Kepler
    Jul 7, 2004
  4. =?Utf-8?B?QXJuZQ==?=

    page.UniqueID

    =?Utf-8?B?QXJuZQ==?=, Dec 7, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    646
    =?Utf-8?B?QXJuZQ==?=
    Dec 7, 2004
  5. Ivan Shmakov
    Replies:
    3
    Views:
    1,231
    Kari Hurtta
    Feb 13, 2012
Loading...

Share This Page