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

Hi all, too much time spent recently using PHP and JavaScript and it seems my brain has gone to jelly ;) I'm working on a Perl project where I'm creating some images using Imager and using the along with some text read from MySQL database in a PDF created with PDF::API2. I can get the job done by writing the images to temp files(s), reading backing to script and then deleting the temp files (unlink), but this seems crazy and I really want to write to and read from a scalar. I'm sure I've done this before, but I've searched old scripts and googled for an answer and have got know where. Can someone please help me. Thanks, Rob

Replies are listed 'Best First'.
Re: Write to and read from scalar
by GrandFather (Saint) on Mar 23, 2012 at 06:30 UTC
    use strict; use warnings; my $str; open my $fOut, '>', \$str; print $fOut "Hello World\n"; close $fOut; open my $fIn, '<', \$str; my $inStr = <$fIn>; close $fIn; print $inStr;

    Prints:

    Hello World
    True laziness is hard work
      Hi, I'm not really sure I get the point. This can be done with a simple assignment $variable = 'xyz'. Then you just print this varible with print $variable. If this is not wat you are looking for please try to describe the problem other way.

        The point is that certain functions expect to be passed filehandles for various purposes.

        Sometimes the data you want to pass to these functions is actually held in a variable. The naive way of coping with that is to write out your data to a temporary file, open the file and pass the filehandle to the function. Often a better solution though is to construct a filehandle which points straight to the scalar variable, and not to a real file on disk.

        Grandfather provides one technique, supported by Perl 5.8+. If (for some perverse reason) you want to support earlier releases of Perl, then IO::String also provides a solution using tied filehandles.

        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

      GrandFather,

      I did it this way from your example. I would not have known how to do this, but the disk file is basically a representation of the scalar.

      my $str = "Hello World\n"; open my $fIn, '<', \$str; my $inStr = <$fIn>; close $fIn; print $inStr;

      Is there a reason to use file I/O to the scalar?

      Thank you

      "Well done is better than well said." - Benjamin Franklin

        For one use reread the OP's node. I frequently use the technique when answering SoPW's where an input file is required. I could write a temporary file then use that, but that adds clutter to the sample.

        In real applications I've used the technique to cache parts of a file that I need to access frequently and to provide a file handle for modules that require them when I really want to pass in a string.

        True laziness is hard work
Re: Write to and read from scalar
by robxbl69 (Novice) on Mar 23, 2012 at 13:06 UTC
    Ahh, that's what I was after. Many thanks ;) However, I can't seem to get PDF::API2's image methods to accept the scalar data as input: $png = $pdf->image_png($file); I know my scalar contains a valid PNG image as I've written the source image to a scalar, closed the file handle, opened another and written the scalar back to disc and the file is a valid PNG. Any ideas on how to do this please? Thanks again.
      $png = $pdf->image_png($file);

      As it looks, the underlying package PDF::API2::Resource::XObject::Image::PNG doesn't expect a (pre-opened) file handle, but a name of a file, which it goes to open itself.

      In case the functionality is important to you, you might want to try modifying the code yourself such that the open is done only in case $file isn't already a valid file handle (check with ref).