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

Hi, all.

This is messy, so let me just fess up to start. Here's a horrible example method:

sub nextrec { local *_ = $_[0]; $_{rec} = <$_{_fh}>; return( (\%_)->errmsg($!) ) if $!; @_{@fields} = unpack $layout, $_{rec}; "FTRL" eq $_{_id} ? 0 : $_{rec}; }
(Note that $obj->errmsg($!) decides according to previous state whether to die with the message, warn() it to STDERR, or just make it available on request and quietly return undef.)

For those who want the details, the object is a blessed hash reference, and the method is invoked by a normal $obj->nextrec syntax. $obj->{_fh} is its open filehandle.

I suspect there's either a small gain for not having allocated lexicals and swapped about the values off the argument stack, or a loss for some esoteric and obscure reason I need to learn. Specifically, however, please note this line:
@_{@fields} = unpack $layout, $_{rec};
I don't know how to do that without aliasing the object to a local()ized hash. I'd like to try something like
$obj->{@fields} = unpack $layout, $_{rec};
but I know that won't work, for fairly obvious reasons.
@{$obj}{@fields} = unpack $layout, $_{rec};
maybe? But that starts getting really ugly again....

Since I have to do the aliasing anyway, I opted for the global default vars, and sprinkled heavily with comments. I know that makes $_ and @_ and %_ all look way too much alike when you access $_[0] and $_{foo}....

....but can someone show me how to assign an array of values to specific fields on an object all at once, so that I don't have to do something like this?
my @vals = unpack $layout, $_{rec}; for my $ndx (0..$#fields) { $obj->{$fields[$ndx]} = $vals[$ndx]; }
I'd rather just use object methods, but I'm squeezing for efficiency, here....but mostly, I just want a cleaner syntax.

Thanks,
Paulie

Replies are listed 'Best First'.
Re: unpack() into object fields
by jasonk (Parson) on Feb 26, 2003 at 22:36 UTC

    I think your slice method (@{$obj}{@fields} = unpack $layout, $_{rec}) is probably the most efficient. 'Cleaner' is in the eye of the beholder, personally I think that syntax is the cleanest as well.

Re: unpack() into object fields
by hv (Prior) on Feb 26, 2003 at 23:49 UTC

    @$obj{@fields} is the only way I know to get a slice of a hashref, but as with many other perl constructs, I found that it seemed ugly only as long as I was unfamiliar with it.

    If you're squeezing for speed efficiency, I think you'd be better off using lexicals: they're normally faster than package variables, because the location of lexicals is determined at compile time, whereas package variables require a run-time hash lookup to find the glob.

    Hugo