in reply to what does main->{x} = 1 do?

Does't work for me with Perl v5.8.8 on Linux:

$ perl -le 'main->{x} = 1; print $main->{x}'

But this does:

$ perl -lwe 'main->{x} = 1; print $main{x}' 1

The reason is that "main" is being treated as a symbolic reference to the global hash %main. Strict mode catches the error for you:

$ perl -Mstrict -lwe 'main->{x} = 1; print $main{x}' Can't use bareword ("main") as a HASH ref while "strict refs" in use a +t -e line 1.

-sam

Replies are listed 'Best First'.
Re^2: what does main->{x} = 1 do?
by ganeshk (Monk) on May 14, 2008 at 00:40 UTC
    Thank you very much Sam and Wade for the response. strict refs mode is fine. But I just wanted to know if I understood right! When you use the -> operator the '$' sigil is not necessary! Perl automatically understands the type i.e whether array or hash. And also the variable is defined in the current package. Is that correct? I actually ran into problem while just trying to auto-generate getter/setters for a class. So just before installing the methods into the target class, the strict 'refs' is turned off! So the getter/setter code was something like this
    sub { if ( @_ == 1 ) { $_[0]->{$name} # this was initially $_[0]{$name} } else { $_[0]->{$name} == $_[1]; # initially $_[0]{$name} = $_[1]; } }
    This seems to be ok as long as the method is called on an object. But say you call the method on a class(say by mistake), then it was causing problems without the arrow operator. But when the arrow operator was included it was working fine although the method was meant to be an object method. So then I saw I needed to brush up some fundametals! So if I understand it correctly what happens here is that the hash variable is actually defined in the package where the code belongs. And it happens because strict refs is off. Thanks in advance for the help. Thanks again!

      When you use the -> operator the '$' sigil is not necessary!

      It has nothing to do with the -> operator. Few if any operators requires its operands to have a $ since they work on expressions, not specifically scalars.

      For example, here are 4 different operators and not a sigil in sight:

      foo()->{x} foo() + bar() !foo() print(foo())

      Perl automatically understands the type i.e whether array or hash.

      Correct.
      EXPR->[...] expects EXPR to return an array reference.
      EXPR->{...} expects EXPR to return a hash reference.
      EXPR->(...) expects EXPR to return a code reference.

      And also the variable is defined in the current package. Is that correct?

      No. Symbolic references can access variables in any package.

      >perl -le"$x='Foo::var'; ${$x}='abc'; print $Foo::var;" abc

      And it happens because strict refs is off.

      strict shouldbe used. It's there to prevent specifically these kinds of odd and hard to debug problems.

      Thank you very much Sam and Wade for the response. strict refs mode is fine. But I just wanted to know if I understood right! When you use the -> operator the '$' sigil is not necessary! Perl automatically understands the type i.e whether array or hash.

      I personally believe you're right. More precisely, with the symrefs thingy others duly explained to you, the -> dereferentiation operator, complete of the correct parens -AFAICS it doesn't exist by itself- is unambiguous enough for the correct slot to be selected. However you should not use symrefs, anyway. (But under particular circumstances.) Rather, I feel like pointing out that main->{x} = 1; is still valid syntax, under strictures, although it has to be associated with a different semantics than yours:

      $ perl -Mstrict -wle ' > my %x; sub main () { \%x }; > main->{x} = 1; > print $x{x}' 1
      --
      If you can't understand the incipit, then please check the IPB Campaign.

      $_[0]->{$name} and $_[0]{$name} are equivalent. Always, no matter the status of use strict 'refs'. The -> between subscripts is optional. This is in no way related to symbolic references or typeglobs or packages.

      If you obtained different results, you must have changed something more.