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

Is there ever a case where:
my $x = some expression;
gives a different result than:
my $x; $x = some epxression;
Assuming some expression does not include $x in it.

Replies are listed 'Best First'.
Re: my $x = <expr>; vs my $x; $x = <expr>;
by Zaxo (Archbishop) on Jun 05, 2004 at 07:32 UTC

    No, they are equivalent as you have written them. I prefer to initialize at the same time I declare lexical, as in your first example. That helps enforce locality of the variable. I generally split them only when $x is set within a smaller scope, but $x is needed in a wider one. An example,

    my $x; { open my $fh, '<', '/path/to/foo.file' or die $! $x = <$fh>; close $fh; }
    $x is available outside the braces, but the apparatus needed to set it is hidden from the rest of the program.

    After Compline,
    Zaxo

      I'd write that as

      my $x = do { open my $fh, '<', '/path/to/foo.file' or die $! <$fh>; };

      Note that $fh is auto-closed due to falling out of scope.

      Update: the last line was not meant to be $x = <$fh> of course.

      Makeshifts last the longest.

        You can't use $x in the same statement as you declare it. Your second use of $x is global. The last line in the block should be just scalar <$fh>

        The PerlMonk tr/// Advocate
Re: my $x = <expr>; vs my $x; $x = <expr>;
by dave_the_m (Monsignor) on Jun 05, 2004 at 11:50 UTC
    No, but beware of
    my $x = expresssion if condition
    Which, due a bug in Perl, causes $x not to be cleared at the end of the block, and so to still have its old value on the next entry to the block, eg
    for (1..3) { my $x = "foo\n" if $_ > 9999; print $x; $x = "bar\n"; }
    which outputs:
    Use of uninitialized value in print at /tmp/p line 5. bar bar

    Dave.

      It's not a bug, it's an accidental feature, and it only happens when the condition is false. It's because the dual nature of my, which has effects both at compile time and at runtime.

      Makeshifts last the longest.

        It's not a bug, it's an accidental feature
        Well, that's a matter of semantics:-) In 5.10.0 the form my $x if 0 will be officially deprecated, and will give a warning (and I should know - I added the warning!). It was felt that benefits of the "feature" for eg pseudo-static variables was outweighed by the unexpectedness of its behavour for most people.

        Dave.

Re: my $x = <expr>; vs my $x; $x = <expr>;
by Abigail-II (Bishop) on Jun 05, 2004 at 22:04 UTC
    Well, if there's a source filter, or if 'some expression' invokes some XS code that walks the parse tree, there might be a difference. But normally, there won't be any semantic difference. There will be a small speed difference though, since the second expression will store an undefined value in $x before assigning 'some expression':
    #!/usr/bin/perl use strict; use warnings; no warnings qw /syntax/; use Benchmark qw /cmpthese/; cmpthese -1 => { single => 'my $x = "foo"', double => 'my $x; $x = "foo"', }; __END__ Rate double single double 2710223/s -- -14% single 3143931/s 16% --

    Abigail