Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Embedding fuction output

by RatArsed (Monk)
on Jun 11, 2001 at 17:43 UTC ( [id://87470]=perlquestion: print w/replies, xml ) Need Help??

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

I'm trying to embed function output into a print <<BLAH block, EG:
my $tnav = CONF::topnav(); my $bnav = CONF::botnav(); print <<EOPAGE <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http:/ +/www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Wibble</title> </head> <body> $tnav <h1 class="header">Wibble</h1> <p>This is purely demo</p> </body> </html> EOPAGE ;
Ideally, for clarity, I'd like to remove the need for the local variables, and just chuck a reference to the fuction into the flow.

So, does Perl provide me with the construct to do this? Am I being completely stupid today?

NB Before anyone gets on to me with "why aren't you using CGI.pm?"; please don't, we have our reasons for not using it for output...

--
RatArsed

Replies are listed 'Best First'.
Re: Embedding fuction output
by mirod (Canon) on Jun 11, 2001 at 17:53 UTC

    You can use the @{[func(@args)]} construct, it's ugly but it works:

    print <<EOPAGE yarri, yarri, @{[CONF::botnav()]} yarra... EOPAGE

    I have never really dug the why of this idiom, the best explanation I can come up with is: [func(@args)] tells Perl that you want to put the result of the function in an anonymous array, and the @{} bit gets the content of that array in a way that is expanded in double-quoted strings (by using EOPAGE without any quotes it defaults to <<"EOPAGE" which treates the following string as double-quoted, nothing would get expanded if you used <<'EOPAGE').

    Now whether this increases clarity or adds to the general confusion... you'll have to decide for yourself!

      and just to add, if you need scalar context make it simply:

      @{[scalar func(@args)]}

      -- Hofmator

      "Now whether this increases clarity or adds to the general confusion..."
      Now that's a good question if you ask me. Be aware that the @{[]} construct allows you to stuff any code inside the square brackets, be it merely a function call or a loop or an ugly if..elsif..elsif..else sequence, or whatever. That's tempting but you're likely to end up with your whole program consisting of a print statement,one big here-document, and all the rest of it scattered here and there in the here-doc.

      I would definitely stay with the option of running the code beforehand to feed any local variable, and then use these variables within the here-docs. Or go a step further and use templating solutions like HTML::Template or the Template Toolkit.

      --bwana147

Re: Embedding fuction output
by maverick (Curate) on Jun 12, 2001 at 02:28 UTC
    If readability is the goal then how about something like this:
    sub foo { return "some output from foo\n"; } print <<' EOPAGE'; some stuff some more stuff EOPAGE print foo(); print <<' EOPAGE'; yet more stuff EOPAGE
    Use the "print <<" construct for ONLY the static html and then call your functions directly. If you indent the different prints at different levels, it will be really easy to pick out which ones are which.

    An alternate solution to consider is using one of the html template systems. This would be some work to convert your existing code over, but it could be worth it.

    I'm going to go out on a limb and bet that you're wanting your code to look something like:

    -------------------------------------- #!/usr/bin/perl Here's all my perl code where I set my variables and do my logic print <<EOP; here's all my html where I put in my $vars and @foos EOP ---------------------------------------
    so that all your html is in one place and your code in another right? Check out http://www.cpan.org/modules/by-module/HTML/HTML-Template-2.2.readme

    /\/\averick

Re: Embedding fuction output
by Odud (Pilgrim) on Jun 11, 2001 at 18:54 UTC
    A different approach: You could do something like
    print qq{Caller's Name: $caller \n};

    But... I don't know how to put in the subroutine/function name directly. Cleverer people than me will know the way though... Hope this is of use...
    Update:
    Initially I though this would work but although it does for the variable the function call is untouched.
    $foo = "bar"; while(<DATA>) { print eval("\"".$_."\""); } __DATA__ line 1 $foo &localtime() line 3
Re: Embedding fuction output
by mattr (Curate) on Jun 11, 2001 at 19:05 UTC
    I was looking at a way to do it with something like

    $str = <<'EOPAGE'; Some html TNAV Some more html EOPAGE $str =~ s/TNAV/$tnav/;
    but it don't work.. maybe best to create a variable by the same name as a keyword that was delimited by % marks..?

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (2)
As of 2024-04-25 07:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found