Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: Way to do a "scalar ref"?

by davido (Archbishop)
on Sep 26, 2011 at 08:46 UTC ( #927819=note: print w/ replies, xml ) Need Help??


in reply to Way to do a "scalar ref"?

Could you elaborate further on why you would want to use a string to represent a variable name? It is possible with Perl (for package globals, not for lexical 'my' variables), and the answer is in perlref, but it's usually the wrong way to resolve whatever programming corner you're painted into. There are a few exceptions, but by the time you find one of the legitimate exceptions you will already know how, and why not.


Dave


Comment on Re: Way to do a "scalar ref"?
Re^2: Way to do a "scalar ref"?
by ultranerds (Pilgrim) on Sep 26, 2011 at 08:51 UTC
    Hi,

    Thanks for the reply. Ok, I'm working on a wiki (which can have VERY large articles in). The site also gets a lot of traffic (several million hits a month), so I need to make this code as optimized as possible. Now, lets say we have:
    sub process_article { my $article = get_article_from_db($article_id); my $contents = process_article($article->{contents}); # now I need to access $article->{contents}, but the modified vers +ion from process_article } sub process_article { my $article_contents = $_[0]; # do some stuff to $article_contents here return $article_contents; }
    ..so basically I wanna be able to pass along $article_contents to different functions, but not actually have it take up more memory (or require a "return", to assign it to a new variable).

    Does that make more sense?

    TIA

    Andy
      FWIW @_ and thus $_[0] are already aliases to the variable used in the call, so if you do something like
      sub f { $_[0] =~ s/a/b/g } my $text = 'foo bar' f $text

      No copying happens.

      If you want explicit references, do it like this:

      sub f { my $ref = shift; $$ref =~ s/a/b/g } my $text = 'foo bar' f \$text
      m working on a wiki (which can have VERY large articles in). The site also gets a lot of traffic (several million hits a month), so I need to make this code as optimized as possible.

      Then be sure to read perlperf, and cache wherever possible. If you cache the rendered version of very large articles, the number of renderings becomes proportional to the number of writes, which is usually much lower than the number or reads.

      You seem to have two process_article subroutines, should we assume the second ought to be called process_article_contents? Perhaps you could pass a reference to the hash value, something like this.

      knoppix@Microknoppix:~$ perl -MData::Dumper -E ' > sub double { $rsVal = shift; $$rsVal *= 2 } > > $rhData = { one => 1, two => 2 }; > say Data::Dumper->Dumpxs( [ $rhData ], [ qw{ rhData } ] ); > > double( \ $rhData->{ two } ); > say Data::Dumper->Dumpxs( [ $rhData ], [ qw{ rhData } ] );' $rhData = { 'one' => 1, 'two' => 2 }; $rhData = { 'one' => 1, 'two' => 4 }; knoppix@Microknoppix:~$

      I hope this is helpful.

      Cheers,

      JohnGG

      You can even save one more large, expensive copy operation by returning a reference to the scalar 'content' in the first place rather than the actual content (if you have editorial control over these functions) and just pass around the scalar reference thereafter. In the example below, the only copy performed is the absolutely necessary one (if you do not want to change the original content) associated with the first processing operation. (Update: Of course, you still have to come to terms with all the copying that goes on in all those  s/// operations, which may make the higher-level question moot.)

      >perl -wMstrict -le "my $article = { content => 'FEE FIE FOE FUM' }; ;; print qq{'$article->{content}'}; my $sr = process_content($article); print qq{'$$sr'}; process_content_some_more($sr); print qq{'$$sr'}; ;; sub process_content { my ($hashref) = @_; (my $processed = $hashref->{content}) =~ s{(\w+)}{\L$1}xmsg; return \$processed; } ;; sub process_content_some_more { my ($scalarref) = @_; $$scalarref =~ s{(\w+)}{\u$1}xmsg; } " 'FEE FIE FOE FUM' 'fee fie foe fum' 'Fee Fie Foe Fum'

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://927819]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (11)
As of 2014-09-30 21:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (384 votes), past polls