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

While writing today's calendar entry I ran into this very odd behavior. I have an lvalue sub using Want across namespaces, but I get odd results. In the same namespace it works fine, and a simplified version also works fine.
#Minimal package A; use Want; sub sub :lvalue{ if( want('LVALUE', 'ASSIGN') ){ print want('ASSIGN'), "\n"; lnoreturn; } if( want('LIST') ){ rreturn 'xyzzy'; } else{ rreturn 'you were eaten by a grue'; } return; } package main; print A::sub, "\n"; print scalar A::sub, "\n"; A::sub() = 42;
Gives:
xyzzy
you were eaten by a grue
42
The full code (toggle the comments):
#To work properly comment out the next line package Xmas; use Want; use Lingua::EN::Numbers::Ordinate; @days = <DATA>; sub days :lvalue { if( want('LVALUE', 'ASSIGN') ){ my $n = shift; $days[$n] = want('ASSIGN'); lnoreturn; } if( want('SCALAR') ){ my $str = ''; foreach( 1..12 ){ $str .= sprintf $days[0], ordinate($_); $str .= join'', reverse(@days[1..$_]), "\n"; } return $str; } if( want('ARRAY') ){ if( my $n = howmany() ){ return @days[1..$n]; } return @days; } } return; } #To work properly comment out the next line, I also tried calling Xmas +::days *main::days = \&days; package main; print scalar days(); days(5) = "Five onion rings!\n"; print scalar days(); __DATA__ On the %s day of Christmas, my true love gave to me A partridge in a pear tree. Two turtle doves Three French hens Four calling birds Five golden rings. Six geese a-laying, Seven swans a-swimming Eight maids a-milking Nine ladies dancing Ten lords a-leaping Eleven pipers piping Twelve drummers drumming
Gives either
















Five onion rings!

Five onion rings!

Five onion rings!

Five onion rings!

Five onion rings!

Five onion rings!

Five onion rings!

Five onion rings!
or the expected result if in the same package
On the 1st day of Christmas, my true love gave to me
A partridge in a pear tree.

On the 2nd day of Christmas, my true love gave to me
Two turtle doves
A partridge in a pear tree.

On the 3rd day of Christmas, my true love gave to me
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 4th day of Christmas, my true love gave to me
Four calling birds
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 5th day of Christmas, my true love gave to me
Five golden rings.
Four calling birds
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 6th day of Christmas, my true love gave to me
Six geese a-laying,
Five golden rings.
Four calling birds
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 7th day of Christmas, my true love gave to me
Seven swans a-swimming
Six geese a-laying,
Five golden rings.
Four calling birds
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 8th day of Christmas, my true love gave to me
Eight maids a-milking
Seven swans a-swimming
Six geese a-laying,
Five golden rings.
Four calling birds
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 9th day of Christmas, my true love gave to me
Nine ladies dancing
Eight maids a-milking
Seven swans a-swimming
Six geese a-laying,
Five golden rings.
Four calling birds
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 10th day of Christmas, my true love gave to me
Ten lords a-leaping
Nine ladies dancing
Eight maids a-milking
Seven swans a-swimming
Six geese a-laying,
Five golden rings.
Four calling birds
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 11th day of Christmas, my true love gave to me
Eleven pipers piping
Ten lords a-leaping
Nine ladies dancing
Eight maids a-milking
Seven swans a-swimming
Six geese a-laying,
Five golden rings.
Four calling birds
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 12th day of Christmas, my true love gave to me
Twelve drummers drumming
Eleven pipers piping
Ten lords a-leaping
Nine ladies dancing
Eight maids a-milking
Seven swans a-swimming
Six geese a-laying,
Five golden rings.
Four calling birds
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 1st day of Christmas, my true love gave to me
A partridge in a pear tree.

On the 2nd day of Christmas, my true love gave to me
Two turtle doves
A partridge in a pear tree.

On the 3rd day of Christmas, my true love gave to me
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 4th day of Christmas, my true love gave to me
Four calling birds
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 5th day of Christmas, my true love gave to me
Five onion rings!
Four calling birds
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 6th day of Christmas, my true love gave to me
Six geese a-laying,
Five onion rings!
Four calling birds
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 7th day of Christmas, my true love gave to me
Seven swans a-swimming
Six geese a-laying,
Five onion rings!
Four calling birds
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 8th day of Christmas, my true love gave to me
Eight maids a-milking
Seven swans a-swimming
Six geese a-laying,
Five onion rings!
Four calling birds
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 9th day of Christmas, my true love gave to me
Nine ladies dancing
Eight maids a-milking
Seven swans a-swimming
Six geese a-laying,
Five onion rings!
Four calling birds
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 10th day of Christmas, my true love gave to me
Ten lords a-leaping
Nine ladies dancing
Eight maids a-milking
Seven swans a-swimming
Six geese a-laying,
Five onion rings!
Four calling birds
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 11th day of Christmas, my true love gave to me
Eleven pipers piping
Ten lords a-leaping
Nine ladies dancing
Eight maids a-milking
Seven swans a-swimming
Six geese a-laying,
Five onion rings!
Four calling birds
Three French hens
Two turtle doves
A partridge in a pear tree.

On the 12th day of Christmas, my true love gave to me
Twelve drummers drumming
Eleven pipers piping
Ten lords a-leaping
Nine ladies dancing
Eight maids a-milking
Seven swans a-swimming
Six geese a-laying,
Five onion rings!
Four calling birds
Three French hens
Two turtle doves
A partridge in a pear tree.

--
In Bob We Trust, All Others Bring Data.

Replies are listed 'Best First'.
Re: Cross-namespace problem with lvalue subs? Want?
by eric256 (Parson) on Dec 22, 2005 at 16:53 UTC

    Your problem has nothing to do with lvalues or want. It actualy has to do with your data tag ann packages. Try the following code to see..

    use strict; use warnings; package TEST; print "Package\n"; my @data = <DATA>; print @data; print "\n"; package main; print "Main\n"; my @data = <DATA>; print @data; print "\n"; __DATA__ 1 2 3 4 5

    ___________
    Eric Hodges $_='y==QAe=e?y==QG@>@?iy==QVq?f?=a@iG?=QQ=Q?9'; s/(.)/ord($1)-50/eigs;tr/6123457/- \/|\\\_\n/;print;
      Yes, I'd actually thought DATA might be the problem but I'd tried playing with it in a different way (loading it in package main before declaring package Xmas, hence it being left a global). Using a pre-populated array like
      @days = split/(?=\n)/, <<EODATA; On the %s day of Christmas, my true love gave to me A partridge in a pear tree. Two turtle doves Three French hens Four calling birds Five golden rings. Six geese a-laying, Seven swans a-swimming Eight maids a-milking Nine ladies dancing Ten lords a-leaping Eleven pipers piping Twelve drummers drumming EODATA
      works, as does reading with <main::DATA>. Freaky. Thanks!

        (This post is substantially the same as what I said in the Chatterbox. I'm posting it here for future reference.)

        [...] works, as does reading with <main::DATA>. Freaky.

        Every module can have a __DATA__ section, so the file handle DATA is tied to a package.

        But that's not special. While there are a few special file handles which are trully global (STDIN, STDOUT, STDERR and ARGV), all others are stored in lexical variables or package variables. For example,

        package AA; open(FILE, '<', $ARGV[0]) or die("open: $!\n"); package BB; print(defined(read(FILE, $buf='', 0))?1:0, "\n"); # 0 package AA; print(defined(read(FILE, $buf='', 0))?1:0, "\n"); # 1

        You could try putting "package Xmas;" on the line before __DATA__ - seems to work for changing which package the DATA filehandle appears in.

        Of course, the other admonition is to not have multiple packages in a single file - it confuses us mere mortals when convention is broken like that. ;-)