Perl question of the day

Ovid on 2006-04-08T23:17:30

While working on Class::CGI, I found myself needing to use the following line of code:

@_ = @_;

I've documented why that's necessary. Can you guess why?


Twenty questions

dws on 2006-04-08T23:28:40

Was tie involved?

Re:Twenty questions

Ovid on 2006-04-08T23:37:44

Nope :)

de-aliasing?

mx.2000 on 2006-04-09T00:10:54

Is this the perl-ish way to pass arguments by-value rather than by-alias?

Re:de-aliasing?

Ovid on 2006-04-09T00:22:53

Bingo! I needed to delete select pairs of items from an import list, but I couldn't do this:

# we don't simply splice out because we're iterating by index
@_[ $i, $i + 1 ] = (undef, undef) if $some_condition;
# and later
@_ = grep { defined } @_;

The array slice assignment gave me a "modification of read-only value" error, hence the @_ = @_; statement.

It all feels rather clumsy, but it works.

Re:de-aliasing?

ChrisDolan on 2006-04-09T01:11:27

Without more code for context, it's hard to see why you need to assign to @_. Why not "my @list = @_" and then work on that more-readable array?

Re:de-aliasing?

Ovid on 2006-04-09T01:22:32

It's because I'm subclassing another module which imports and I do and old trick:

goto &Some::SuperClass::import;

This doesn't update caller so I have no worries about whether or not the superclass checks the calling package and gets it wrong. However, it requires that @_ be present. By copying that variable to a separate array, I'd essentially be doing this:

my @array = @_;
# diddle @array
@_ = @array;

I didn't see any value in introducing a temporary variable.

Re:de-aliasing?

Aristotle on 2006-04-09T10:11:40

You can’t adjust your cursor(s) to account for the missing elements?

(Btw, I guessed that it was for de-aliasing before I read the comments saying so.)

Re:de-aliasing?

jsn13 on 2006-04-09T07:07:00

why not just splice(@_, $i, 2) (or probably splice(@_, $i, 2, undef, undef), if you really need these undefs)?

Re:de-aliasing?

Ovid on 2006-04-09T08:20:13

I can't do the first because while I'm doing that, I'm iterating over the array by index. By using splice, I alter where everything is in the array and the indices are off. As for the second, I just didn't think about that. The array slice is what occurred to me first.

Re:de-aliasing?

bart on 2006-04-09T08:19:06

I sometimes do this:
for (@_ = @_) {
    # Now it's safe to modify $_
    # and still leave the original passed arguments intact
    # for example:
    tr/ \n\t/ /s;
}
Sometimes you just don't need a new array.

Re:de-aliasing?

joel h on 2006-04-09T00:23:02

seconded.

At least, it seems to have that effect. Why it is "designed" this way is not obvious to me...

Re:de-aliasing?

joel h on 2006-04-09T00:25:01

doh!

overloading

drhyde on 2006-04-12T10:34:19

I'll guess that something in @_ has overloaded some operations, and by doing that you just get its value (perhaps after being stringified or numified) without any extra clever shit. It's something I've had to do too although in my case I just performed what looked like a null-op on just the one scalar.

Now I'll go and read the other comments to see how wrong I am.