Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

References

by Cine (Friar)
on Aug 19, 2001 at 16:50 UTC ( [id://106017]=perlquestion: print w/replies, xml ) Need Help??

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

How do I alter a to behave like b, while keeping my %c?
That is how to make the final line print ab while using the construct $c{a} = 'a' somehow in a.
sub a { my $ref = shift; my %c = %$ref; $c{a} = 'a'; } sub b { my $c = shift; $$c{b} = 'b'; } my %c; &a(\%c); &b(\%c); print foreach (keys %c);

Replies are listed 'Best First'.
Re (tilly) 1: References
by tilly (Archbishop) on Aug 19, 2001 at 16:58 UTC
    Personally I would suggest learning to live with the syntax rather than fighting it. But there are 2 solutions:
    # Abuse the symbol table. This does not work under strict. sub a1 { local *c = shift; $c{a} = 'a'; } # Copy the hash by force. Very inefficient. sub a2 { my $ref = shift; my %c = %$ref; $c{a} = 'a'; %$ref = %c; }
    However personally I would use the following solution instead as the best mix of safe, efficient, and readable programming with references:
    # "Arrow" notation. sub a3 { my $ref = shift; $ref->{a} = 'a'; } # Or compactly sub a4 { (shift)->{a} = 'a'; }
    TIMTOWTDI.
      sub a1 { local *c = shift; $c{a} = 'a'; }
      Is almost what I want, but it will not work under strict, as you point out.
      I have however come up with two sollutions based on the same idea...
      1
      sub f { use vars qw(%d); local *d = shift; $d{f}='f'; }
      However this will declare %d globally, which is not what I want. so:
      2
      sub f { our %d; local *d = shift; $d{f}='f'; }
      But since I dont know how our works, I dont know how this works... Can someone explain?
        Our is a Perl 5.6 feature that gives lexically scoped access to a global variable. I dislike it for a number of reasons that are neither here nor there, but it should work from Perl 5.6.0 onwards.

        However for several reasons, not the least of which is that some day someone else will have to figure out your code and you will need to understand yet another person's, I strongly recommend getting used to the arrow syntax for dereferencing rather than playing games with the symbol table.

Re: References
by japhy (Canon) on Aug 19, 2001 at 16:55 UTC
    You can include a reassignment to %$ref at the end of the function:
    %$ref = %c;
    Or you can use a local variable and create an alias:
    use vars '%c'; # if strict is on, which it IS, RIGHT? *c = $ref;
    Now, %c is really an alias to %$ref, so changes to one will show in the other.

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker.
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Re: References
by cLive ;-) (Prior) on Aug 19, 2001 at 23:35 UTC
    You can also amend %c direct:
    sub a { ${$_[0]}{a} = 'a'; }
    but I'm not really sure what your question is asking :)

    cLive ;-)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (5)
As of 2024-04-23 08:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found