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

I have often wondered how I can take the results of a function call that returns a scalar, and immediately pass a reference to that scalar to another function. It seems easy enough to do with Arrays and Hashes, but is it possible with Scalars?

sub get_string { return "the string" } sub put_string_ref { my $ref = shift; print "$ref -> $$ref\n"; } # Can I reduce the following two lines to one my $string = get_string(); &put_string_ref(\$string);

I have tried several things, like the following:

put_string_ref(\{get_string()}); put_string_ref(\${get_string()}); put_string_ref(\$&get_string); put_string_ref(\{&get_string});

but can't find anything that works. Am I missing the obvious, or is this just not possible?

In case anyone is wondering why I want to do this, I quite often take the output of HTML::Template and pass it to HTML::FillInForm as a scalar ref.

Replies are listed 'Best First'.
Re: Working with references to scalars
by hv (Prior) on May 09, 2003 at 01:55 UTC

    Try:

    put_string_ref(\(get_string()));

    This works for the same reason that:

    @a = \($a, $b, $c);
    puts three references into @a.

    Hugo

      I knew I should have tried more variations. I guess I always automatically associate lists with arrays and had already excluded round brackets in my mind for that reason.

      Thanks for the answer, and I will try to keep in mind that lists are not the same as arrays...

      As a follow up to this question though, why doesn't \(&get_string) work. I guess there must be a difference between &func and func(), but I have never come across this in my readings.

        put_string_ref( \(&get_string) ); works for me.

        According to perldoc perlsub, the & is optional as are the parentheses if the subroutine has been predeclared. The & is not optional when just naming the subroutine. Nor is it optional when you do an indrect subroutine call with a subroutine name or reference using the &$subref() or &{$subref}() constructions, although the $subref->() notatation solves that problem.

Re: Working with references to scalars (even easier)
by tye (Sage) on May 09, 2003 at 03:25 UTC

    You don't even need the parens that hv and apsyrtes used:

    put_string_ref( \get_string() );
    works just fine for me.

                    - tye
Re: Working with references to scalars
by apsyrtes (Beadle) on May 09, 2003 at 02:05 UTC
    Regular brackets worked for me.

    put_string_ref(\(get_string()));


    Jason W.
Re: Working with references to scalars
by hmerrill (Friar) on May 09, 2003 at 13:26 UTC
    I find myself frequently being an advocate for non-obfuscated code - I think your original code
    my $string = get_string(); put_string_ref(\$string);
    is very simple and clear and easily understood. I'm sure some people will disagree with me here, but IMHO doing
    put_string_ref(\get_string())
    is at least somewhat obfuscated. It kind of begs the question "What am I passing to put_string_ref? Is it a reference to the get_string subroutine, or is it a reference to the string that get_string returns?". It is not absolutely clear looking at that code *what* is being passed to put_string_ref.

    Again, just my opinion, but your original code is better since it is very clear about what it is doing - self documenting code is best. If you need to spend time figuring out what it does, then chances are it could have been written in a more understandable and more easily maintainable way.

    HTH.

      I agree that my example wouldn't be a good case of clear coding style, but I was only trying to create a simple example. How I will use it like this:

      use HTML::Template(); use HTML::FillInForm(); use CGI(); my $string = '<b><TMPL_VAR test></b>'; my $query = new CGI; my $template = new HTML::Template(scalarref => \$string); my $fif = new HTML::FillInForm; print $fif->fill(scalarref => \$template->output(), fobject => $query);

      In this case it clearly states that the fill method expects a reference to a scalar. I prefer the above code over this (the old way I always used)

      my $html = $template->output(); print $fif->fill(scalarref => \$html, fobject => $query);