Re: On References to the Unnamed
by jdporter (Paladin) on Mar 15, 2005 at 17:29 UTC
|
But bless \"$_", 'Foo' doesn't even work: Modification of a read-only value attempted...
You could make a "factory" for scalar refs:
sub new_scalar_ref { my $x; \$x }
Of course, this technique can be used in-line with do, if you prefer.
Another idea you could consider is to bless an anonymous sub. That, at least, will throw
an exception if a client ever tries to deref it as data.
| [reply] [d/l] [select] |
|
|
| [reply] [d/l] [select] |
|
|
sub new_scalar_ref { \my $x }
| [reply] [d/l] |
|
|
|
|
|
|
|
Another is in Getopt::Long (example slightly golfed)
GetOptions('in|i=s' => \my $indir,
'out|o=s' => \my $outfile,
'log|l=s' => \my $logfile,
'cp|c=s' => \my $cp,
'help|?' => \my $help,
man => \my $man) or pod2usage(2);
...it is better to be approximately right than precisely wrong. - Warren Buffet
| [reply] [d/l] |
|
|
What??? It works perfectly well on my system (Linux), both with Perl 5.6.1 and Perl 5.8.4. No error messages at all.
Perl is an endless source of wonderment...
| [reply] |
Re: On References to the Unnamed
by Anonymous Monk on Mar 15, 2005 at 17:42 UTC
|
I find it quite surprising that \"$a" creates a reference to an lvalue, since "$a" isn't an lvalue. This might be a bug, or an artifact of the implementation of perl. Unless I'd find a place where this is documented, I wouldn't count on it working on a next version of perl.
If I want a scalar to an anonymous scalar, I use:
\do {my $foo}; # Or do {\my $foo};
which is an well-known technique, and before we had auto-vivifying filehandles, similar to how we created references to filehandles (\do {local *FOO}).
As for sizes, \"$$" takes 2.5 times the memory \do {my $foo} takes. And even \"" takes more than twice the memory. This is because \do {my $foo} is just an SV, pointing to nothing. (The flag ROK says it's a reference). But \"" still has to point to something.
#!/usr/bin/perl
use strict;
use warnings;
use Devel::Size 'total_size';
use Devel::Peek;
my $a = \"$$";
my $b = \"";
my $c = \do {my $foo};
print total_size($a), "\n";
print total_size($b), "\n";
print total_size($c), "\n";
print "-----\n";
print Dump($a);
print Dump($c);
__END__
30
25
12
-----
SV = RV(0x81c1df4) at 0x8191e58
REFCNT = 1
FLAGS = (PADBUSY,PADMY,ROK)
RV = 0x8184180
SV = PV(0x8184494) at 0x8184180
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x8189cf8 "23192"\0
CUR = 5
LEN = 6
SV = RV(0x81c1dfc) at 0x8191eac
REFCNT = 1
FLAGS = (PADBUSY,PADMY,ROK)
RV = 0x8191f84
SV = NULL(0x0) at 0x8191f84
REFCNT = 2
FLAGS = (PADBUSY,PADMY)
| [reply] [d/l] [select] |
Re: On References to the Unnamed
by Juerd (Abbot) on Mar 15, 2005 at 21:01 UTC
|
Wouldn't it be much easier to just introduce a perlvar that each time it's used, is a new scalar? I suggest $^N, New scalar.
bless \$^N, $class;
bless \($^N = "some value"), $class;
I don't really see why this is needed, though. I can live with
bless \my $dummy, $class;
or, if for some strange reason I don't want to pollute the lexical scope with a $dummy,
bless \do { my $dummy }, $class;
| [reply] [d/l] [select] |
|
|
sub new {
my $class = shift;
bless \$class, $class;
}
| [reply] [d/l] |
|
|
$^N is already taken.
ihb
See perltoc if you don't know which perldoc to read!
| [reply] [d/l] |
Re: On References to the Unnamed
by hardburn (Abbot) on Mar 15, 2005 at 20:08 UTC
|
Quoting is not an identity function in Perl. Don't treat it like one or you'll eventually get bitten.
Make a proper identity function instead (simplified to only return the first arg instead of all of them):
sub ident { shift }
bless \(ident($_)) => 'Foo' for 3;
A little more typing? Yes. Avoids subtle bugs? Yes :)
"There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.
| [reply] [d/l] |
|
|
Quoting is not an identity function in Perl.
That's the point of \"$_", isn't?
| [reply] [d/l] |
|
|
| [reply] [d/l] |
Re: On References to the Unnamed
by Roy Johnson (Monsignor) on Mar 16, 2005 at 15:40 UTC
|
This generates a list of anonymous scalars:
\@{[]}[0..49]
Taking a reference to a slice yields a reference to each member (it's \ operating on a list). Generating one ref requires the same number of chars as Larry's, and is substantially slower. But if you ever need to generate a substantial list of scalar refs (it catches up at around 20, compared to using map with Larry's), this would be the way to go.
And with all due respect to Larry, here's a golfier way to get a single scalar ref:
\[]->[0]
Now, for the case you mention, in which you merely need a stateless object...well, you don't need an object. You just do everything through class methods. But taking a reference to a constant would work. You don't need an anonymous scalar, because you're not going to modify the contents.
You'd want a scalar when you have an object with only one property. In that case, you'd just declare a lexical scalar in your constructor, and bless a reference to it. So you still don't need anonymous scalars.
Caution: Contents may have been coded under pressure.
| [reply] [d/l] [select] |
A reply falls below the community's threshold of quality. You may see it by logging in. |
Re: On References to the Unnamed
by mstone (Deacon) on Mar 16, 2005 at 19:48 UTC
|
sub anon_ref {
$N ||= 1;
my $name = sprintf "var%04d", $N;
my $ref = \${ 'NAMESPACE::' . $name };
delete $NAMESPACE{ $name };
$N++;
return ($ref);
}
It does use a name to create the variable, but then deletes that name from the symbol table, which arguably results in an anonymous scalar.
In an object constructor, it would looks like so:
sub My_object::new {
my ($type, @data) = @_;
$N ||= 1;
my $name = sprintf "var%04d", $N;
my $object = \${ 'NAMESPACE::' . $name };
delete $NAMESPACE{ $name };
$N++;
bless $object, $type;
$object->configure_with (@data);
return ($object);
}
or you can factor the ref code out into a separate function and just use:
sub My_object::new {
my $O = bless anon_ref(), shift;
$O->configure_with (@_);
return ($O);
}
By tweaking the specific kind of ref you create in anon_ref(), you can make it return scalars, lists, hashes, or entire globs. Most of the File:: classes use anonymous globs to store their filehandles, in fact.. | [reply] [d/l] [select] |
Re: On References to the Unnamed
by eyepopslikeamosquito (Archbishop) on May 28, 2005 at 13:49 UTC
|
$anon_scalar_ref = \eval{undef}; # or ...
$anon_scalar_ref = \eval{ $init_val }; # if you prefer anon scalar in
+itialized
Running:
#!/usr/bin/perl
use strict;
use warnings;
use Devel::Size 'total_size';
use Devel::Peek;
my $a = \"$$";
my $b = \"";
my $c = \do {my $foo};
my $d = \eval{undef};
print total_size($a), "\n";
print total_size($b), "\n";
print total_size($c), "\n";
print total_size($d), "\n";
print "-----\n";
print Dump($a);
print Dump($c);
print Dump($d);
produced:
29
25
12
12
-----
SV = RV(0x1865b28) at 0x18242d8
REFCNT = 1
FLAGS = (PADBUSY,PADMY,ROK)
RV = 0x224f08
SV = PV(0x2251fc) at 0x224f08
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x1834234 "3484"\0
CUR = 4
LEN = 5
SV = RV(0x1865b30) at 0x18242e4
REFCNT = 1
FLAGS = (PADBUSY,PADMY,ROK)
RV = 0x186168c
SV = NULL(0x0) at 0x186168c
REFCNT = 2
FLAGS = (PADBUSY,PADMY)
SV = RV(0x1865b34) at 0x18247a4
REFCNT = 1
FLAGS = (PADBUSY,PADMY,ROK)
RV = 0x224fbc
SV = NULL(0x0) at 0x224fbc
REFCNT = 1
FLAGS = ()
| [reply] [d/l] [select] |