in reply to Re: Re: %hash (@array && use constant) in Modules
in thread %hash (@array && use constant) in Modules

"Should get" versus "do get" is an important distinction. Have a look inside constant and see:
{ no strict 'refs'; my $full_name = "${pkg}::$name"; $declared{$full_name}++; if (@_ == 1) { my $scalar = $_[0]; *$full_name = sub () { $scalar }; } elsif (@_) { my @list = @_; *$full_name = sub () { @list }; } else { *$full_name = sub () { }; } }
Looks like a regular subroutine for me. No inline. Maybe in Perl 6.

Replies are listed 'Best First'.
Re: Re^3: %hash (@array && use constant) in Modules
by samtregar (Abbot) on Apr 23, 2002 at 22:37 UTC
    Incorrect. If it looks like a regular subroutine to you that only means you don't know what an inlined subroutine looks like! I suggest you spend some time with Benchmark and prove to yourself that "use constant" really does result in inlined subroutines.

    -sam

      Time well spent. Thanks for the insight, samtregar, and Elian. Two letters, '()', can make a whole lot of difference. Wow.

      I've been trying to kill off references to Tie::Const, a deprecated module from ages ago, and now I think this might just do the trick.
Re: Re^3: %hash (@array && use constant) in Modules
by ariels (Curate) on Apr 24, 2002 at 06:00 UTC
    Benchmarking tells you if something is faster or not. B::Deparse tells you how Perl compiled your code. Both are useful in a case like this, so here's the Deparse way...
    <mir 112 [8:56] ~ >perl -MO=Deparse -le 'use constant X=>17; print X' -e syntax OK sub X () { package constant; $scalar; } print 17;
Re: Re^3: %hash (@array && use constant) in Modules
by Dice (Beadle) on Apr 24, 2002 at 13:24 UTC

    When the person above you said 'inline', I don't think he was referring to Inline::C or anything like that. Rather, that the Perl compiler knows to optimize "constant" subroutines at compile-time and replace its subroutine/stack-calling stuff with... well, constant values

    As an example, I created a program around the "Foo" package example we're using here, and I expanded the "Foo" package as well. Here it is:

    #!/usr/bin/perl -w
    
    use strict;
    
    my $foo = Foo->new();
    
    $foo->setBar('10');
    
    print "\$foo's 'bar' value is = " . $foo->getBar() . "\n";
    
    exit 0;
    
    package Foo;
    
    use constant BAR      => 1;
    use constant BAZ      => 2;
    use constant SO_ON    => 3;
    use constant SO_FORTH => 4;
    
    sub new {
        return bless ([], +shift);
    }
    
    sub getBar {
        my $self = shift;
        $self->BAR;
    }
    
    sub setBar {
        my $self = shift;
        $self->BAR = +shift;
    }
    

    Now, look at what this looks like when I run it through B::Deparse

    rdice@tanru:~$ perl -MO=Deparse,-uFoo constants.pl
    my $foo = 'Foo'->new;
    $foo->setBar('10');
    print q($foo's 'bar' value is = ) . $foo->getBar . "\n";
    exit 0;
    sub Foo::BAR () {
        package constant;
        $scalar;
    }
    sub Foo::BAZ () {
        package constant;
        $scalar;
    }
    sub Foo::SO_ON () {
        package constant;
        $scalar;
    }
    sub Foo::SO_FORTH () {
        package constant;
        $scalar;
    }
    sub Foo::new {
        package Foo;
        return bless([], shift @_);
    }
    sub Foo::getBar {
        package Foo;
        my $self = shift @_;
        $$self1;
    }
    sub Foo::setBar {
        package Foo;
        my $self = shift @_;
        $$self1 = shift @_;
    }
    constants.pl syntax OK
    

    This is a reflection of how Perl sees this program after compilation and optimization. Notice that there is NO subroutine call within sub Foo::getBar or sub Foo::setBar with regards to the BAR 'constant', which is really a subroutine, but has been optimized back to being a constant -- namely, "1".

    Cheers,
    Richard