Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

return Both ARRAY and SCALAR

by FutureBoyNil (Initiate)
on May 01, 2009 at 13:17 UTC ( [id://761281]=perlquestion: print w/replies, xml ) Need Help??

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

Good day honorable monks. I humbly come to these gates seeking enlightment. I want a function to return a variable with both SCALAR and ARRAY values. It works for regular functions:
sub XX{
	my $x = 'one'; #scalar value
	push(@{$x}, 'two'); #overload array
	push(@{$x}, 'three'); #overload array
	return $x;
}

my $y = XX(); # typecastable scalar!
print join(", ",$y, @{$y}); # prints "one, two, three"
But as soon as I make it a module, this behaviour dissapears! so:
use MYMOD;
my $x = MYMOD->new();

my $y = $x->XX(); # $y is SCALAR only...
The reason is that I wrote a standalone data parser, and, just like xml, a tag can have multiple ocurrences, thus it is not guaranteed to be unique, but it could be. For now I use get_value() and get_values().

Replies are listed 'Best First'.
Re: return Both ARRAY and SCALAR
by jhourcle (Prior) on May 01, 2009 at 13:25 UTC

    You wouldn't have gotten that behaviour if you had 'use strict'.

    You're not actually overloading, what's happening is that you're assigning to an array based on the name of the variable:

    sub XX{ my $x = 'one'; #scalar value push(@{$x}, 'two'); # push(@one, 'two') push(@{$x}, 'three'); # push(@one, 'three') return $x; }

    Once it's in a module, '@one' is out of scope. If you really want this exact behaviour, you're likely going to need to look into a tied array that stringifies to your 'scalar' value.

Re: return Both ARRAY and SCALAR
by almut (Canon) on May 01, 2009 at 13:37 UTC
    I want a function to return a variable with both SCALAR and ARRAY values.

    Couldn't you use wantarray to make the method return either a single value (in scalar context) or more values (in list context)?

Re: return Both ARRAY and SCALAR
by JavaFan (Canon) on May 01, 2009 at 13:56 UTC
    use 5.010; use strict; use warnings; package Foo; use overload '""' => sub {${$_[0]}{SCALAR}}, '@{}' => sub {${$_[0]}{ARRAY}} ; sub XX { bless {SCALAR => 'one', ARRAY => ['two', 'three']}, shift; } package main; my $y = Foo->XX; say join ", ", $y, @$y; __END__ one, two, three
      This is exactly what I was looking for. Thank you very much!
Re: return Both ARRAY and SCALAR
by Mutant (Priest) on May 01, 2009 at 13:34 UTC
    Instead of doing what you're doing, you could just store everything in an array. Then for fields you know have only one value, just do:
    my ($field) = $parser->get_values();
    Not perfect, but probably cleaner than the approach you're trying to take. (Whether it's useful or not will depend on exactly how you're using this data, which you haven't explained).

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://761281]
Approved by jettero
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (3)
As of 2024-04-20 01:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found