Alternative to Export for constants

Discussion in 'Perl Misc' started by kj, Feb 12, 2004.

  1. kj

    kj Guest

    One thing that bugs me about the Export module is that even when
    you want the module to export everything, one still has to register
    things in @EXPORT. I find it particularly annoying in cases when
    I have a module that contains only constants to be shared by other
    modules and scripts, like this:

    # file My_Constants.pm
    package My_Constants;
    use base 'Exporter';
    our @EXPORT = qw(FOO BAR ... );
    use constant FOO => 1;
    use constant BAR => 4;
    # etc.
    1;

    # file some_script.pl
    use My_Constants;

    printf "%d %d\n", FOO, BAR;



    Instead, I think I would prefer to do something like this:



    # file My_Constants.pm
    package My_Constants;
    use constant FOO => 1;
    use constant BAR => 4;
    # etc.
    1;

    # file some_script.pl
    use My_Constants;

    our $Const = bless \{ my $c }, 'My_Constants';

    printf "%d %d\n", $Const->FOO, $Const->BAR;



    It works, though I've never thing anything like this done. Is
    there anything particularly wrong with it?

    Thanks,

    kj
     
    kj, Feb 12, 2004
    #1
    1. Advertising

  2. kj

    Ben Morrow Guest

    kj <> wrote:
    >
    > One thing that bugs me about the Export module is that even when

    ^^ er
    > you want the module to export everything, one still has to register
    > things in @EXPORT. I find it particularly annoying in cases when
    > I have a module that contains only constants to be shared by other
    > modules and scripts, like this:
    >
    > # file My_Constants.pm
    > package My_Constants;
    > use base 'Exporter';
    > our @EXPORT = qw(FOO BAR ... );
    > use constant FOO => 1;
    > use constant BAR => 4;
    > # etc.
    > 1;

    <snip>
    > # file My_Constants.pm
    > package My_Constants;
    > use constant FOO => 1;
    > use constant BAR => 4;
    > # etc.
    > 1;
    >
    > # file some_script.pl
    > use My_Constants;
    >
    > our $Const = bless \{ my $c }, 'My_Constants';
    >
    > printf "%d %d\n", $Const->FOO, $Const->BAR;
    >
    > It works, though I've never thing anything like this done. Is
    > there anything particularly wrong with it?


    You won't get constant inlining, and the interface is messy (do you
    really want to have to do that 'bless' every time you use the module?)

    A better answer is something like

    package My_Constants;

    use constant;
    use base qw/Exporter/;

    my %consts = (
    FOO => 1,
    BAR => 2,
    );

    our @EXPORT = keys %consts;
    for (keys %consts) {
    import constant $_ => $consts{$_};
    }

    1;

    Ben

    --
    It will be seen that the Erwhonians are a meek and long-suffering people,
    easily led by the nose, and quick to offer up common sense at the shrine of
    logic, when a philosopher convinces them that their institutions are not based
    on the strictest morality. [Samuel Butler, paraphrased]
     
    Ben Morrow, Feb 12, 2004
    #2
    1. Advertising

  3. kj

    Ben Morrow Guest

    Ben Morrow <> wrote:
    > kj <> wrote:
    > >
    > > our $Const = bless \{ my $c }, 'My_Constants';
    > >
    > > printf "%d %d\n", $Const->FOO, $Const->BAR;
    > >
    > > It works, though I've never thing anything like this done. Is
    > > there anything particularly wrong with it?


    Another, stronger, objection is that this comes under the heading
    'using the symbol table when you could use an ordinary hash' (method
    calls are, essentially, symrefs).

    package My_Constant;

    use base qw/Exporter/;
    our @EXPORT = qw/%Consts/;

    out %Consts = (
    FOO => 1,
    BAR => 2,
    );

    1;

    package main;

    use My_Constant;

    print $Const{FOO}, $Const{BAR};

    Ben


    --
    It will be seen that the Erwhonians are a meek and long-suffering people,
    easily led by the nose, and quick to offer up common sense at the shrine of
    logic, when a philosopher convinces them that their institutions are not based
    on the strictest morality. [Samuel Butler, paraphrased]
     
    Ben Morrow, Feb 12, 2004
    #3
  4. kj

    Jay Tilton Guest

    kj <> wrote:

    : One thing that bugs me about the Export module is that even when
    : you want the module to export everything, one still has to register
    : things in @EXPORT. I find it particularly annoying in cases when
    : I have a module that contains only constants to be shared by other
    : modules and scripts, like this:
    :
    : # file My_Constants.pm
    : package My_Constants;
    : use base 'Exporter';
    : our @EXPORT = qw(FOO BAR ... );
    : use constant FOO => 1;
    : use constant BAR => 4;
    : # etc.
    : 1;

    If your complaint is about having to maintain the constants and the
    @EXPORT array in parallel, you could do:

    my %c;
    BEGIN {
    %c = (
    FOO => 1,
    BAR => 4,
    );
    }
    use constant \%c;
    use base 'Exporter';
    our @EXPORT = keys %c;

    : Instead, I think I would prefer to do something like this:
    :
    : # file My_Constants.pm
    : package My_Constants;
    : use constant FOO => 1;
    : use constant BAR => 4;
    : # etc.
    : 1;
    :
    : # file some_script.pl
    : use My_Constants;
    :
    : our $Const = bless \{ my $c }, 'My_Constants';
    ^^^^^^^^^^
    What's that "my $c" thing in the anonymous hash supposed to be?

    Why are you taking a reference to that anonymous hash?

    You don't need to bless anything. Just " $Const = 'My_Constants'; "
    will work just fine for what you're doing.

    : printf "%d %d\n", $Const->FOO, $Const->BAR;
    :
    : It works, though I've never thing anything like this done. Is
    : there anything particularly wrong with it?

    Nothing really wrong with it, except it's rather noisy.

    Does prefacing every constant name with "$Const->" really save work over
    setting up the module to export them?

    Does writing "$Const->FOO" give significant benefit over writing
    "My_Constants::FOO" ? I can see it being useful for swapping out one
    set of constants for another by changing the value in $Const, but I
    can't see needing that capability very often.
     
    Jay Tilton, Feb 12, 2004
    #4
  5. kj

    kj Guest

    In <c0gh7u$g59$> Ben Morrow <> writes:

    >Ben Morrow <> wrote:
    >> kj <> wrote:
    >> >
    >> > our $Const = bless \{ my $c }, 'My_Constants';
    >> >
    >> > printf "%d %d\n", $Const->FOO, $Const->BAR;
    >> >
    >> > It works, though I've never thing anything like this done. Is
    >> > there anything particularly wrong with it?


    >Another, stronger, objection is that this comes under the heading
    >'using the symbol table when you could use an ordinary hash' (method
    >calls are, essentially, symrefs).


    >package My_Constant;


    >use base qw/Exporter/;
    >our @EXPORT = qw/%Consts/;


    >out %Consts = (
    > FOO => 1,
    > BAR => 2,
    >);


    >1;


    >package main;


    >use My_Constant;


    >print $Const{FOO}, $Const{BAR};





    Doh!

    Thanks.

    kj
     
    kj, Feb 12, 2004
    #5
  6. kj

    Anno Siegel Guest

    Ben Morrow <> wrote in comp.lang.perl.misc:
    >
    > kj <> wrote:
    > >
    > > One thing that bugs me about the Export module is that even when

    > ^^ er
    > > you want the module to export everything, one still has to register
    > > things in @EXPORT. I find it particularly annoying in cases when
    > > I have a module that contains only constants to be shared by other
    > > modules and scripts, like this:
    > >
    > > # file My_Constants.pm
    > > package My_Constants;
    > > use base 'Exporter';
    > > our @EXPORT = qw(FOO BAR ... );
    > > use constant FOO => 1;
    > > use constant BAR => 4;
    > > # etc.
    > > 1;

    > <snip>
    > > # file My_Constants.pm
    > > package My_Constants;
    > > use constant FOO => 1;
    > > use constant BAR => 4;
    > > # etc.
    > > 1;
    > >
    > > # file some_script.pl
    > > use My_Constants;
    > >
    > > our $Const = bless \{ my $c }, 'My_Constants';
    > >
    > > printf "%d %d\n", $Const->FOO, $Const->BAR;
    > >
    > > It works, though I've never thing anything like this done. Is
    > > there anything particularly wrong with it?

    >
    > You won't get constant inlining, and the interface is messy (do you
    > really want to have to do that 'bless' every time you use the module?)


    The "bless" is a red herring. Instead of generating an irrelevant object
    to call the constant through, it can be called directly as a class method:

    My_Constants->FOO;

    It's clearly not quite clean. The constant will be called with an argument,
    (class or object, either way), which its prototype actually forbids. It
    only works because prototypes are ignored in method calls. Further, there
    is no advantage in the class method call over the fully qualified
    "My_Constants::FOO". If inheritance is intended, I'd urgently recommend
    not using constants but writing standard methods.

    [snip good exporting alternative]

    Anno
     
    Anno Siegel, Feb 12, 2004
    #6
    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. Benjamin Todd

    constants declaration

    Benjamin Todd, Feb 12, 2004, in forum: VHDL
    Replies:
    2
    Views:
    6,148
    Benjamin Todd
    Feb 15, 2004
  2. =?Utf-8?B?RGF2aWQgVmFsbGU=?=

    Invalid export DLL or export format

    =?Utf-8?B?RGF2aWQgVmFsbGU=?=, Oct 29, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    3,641
    =?Utf-8?B?RGF2aWQgVmFsbGU=?=
    Oct 29, 2003
  3. lnenov
    Replies:
    2
    Views:
    215
    lnenov
    Nov 11, 2010
  4. Maarten Porters
    Replies:
    1
    Views:
    436
    Florian Gilcher
    Jul 28, 2008
  5. Steve Allan
    Replies:
    5
    Views:
    768
    Steve Allan
    Jul 29, 2003
Loading...

Share This Page