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

#!/usr/bin/perl use strict; use warnings; print "Hoeveel?\n"; my $hoeveel = <STDIN>; chomp $hoeveel; print "You typed: $hoeveel\n"; my $y = -931.96483; my $z = 1000; my $a= <<EOT; <g transform="translate(-124.85653,$y)" id="layer$z"> <text xml:space="preserve" style="font-style:normal;font-variant:normal;font-weight:normal +;font-stretch:normal;font-size:126.0375061px;line-height:125%;font-fa +mily:Arial;-inkscape-font-specification:'Arial, Normal';text-align:st +art;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-ancho +r:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stro +ke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" x="-45.714272" y="235.21936" id="text3336"><tspan id="tspan3338" x="-45.714272" y="235.21936">a</tspan></text> </g> EOT for (my $i=1; $i <= $hoeveel; $i++) { my $y = $y + 155; my $z = $z +1; print "$a\n"; };
It is obvious what I want to do here: I want to enlarge $y with 155 and $z with 1 by $hoeveel times. But how to do it?

Replies are listed 'Best First'.
Re: Enlarging scalars
by huck (Prior) on Jun 12, 2017 at 12:47 UTC

    I suspect you want this instead

    for (my $i=1; $i <= $hoeveel; $i++) { $y = $y + 155; $z = $z +1; print "$a\n"; };
    The extra my commands isolated the variables outside of the loop from any changes but it also meant the inner variables became almost static

      What's the difference?

        The original code had my $z = $z + 1;, this code has $z = $z + 1;

        Like huck already said, "The extra my commands isolated the variables outside of the loop from any changes but it also meant the inner variables became almost static".

        Using my $z you declare a second variable named $z, which shadows the first variable named $z declared at the top of your script. All statements mentioning $z will refer to that shadowing $z until execution leaves the block for the next loop iteration. In the next iteration, a new shadowing $z is created and all changes made previously have been lost.

        use strict; use warnings; { print "using exterior values\n"; my $y=1; my $z=1; my $hoeveel=5; for (my $i=1; $i <= $hoeveel; $i++) { $y = $y + 155; $z = $z +1; print "$y $z\n"; }; } { print "using localizing interior values\n"; my $y=1; my $z=1; my $hoeveel=5; for (my $i=1; $i <= $hoeveel; $i++) { my $y = $y + 155; my $z = $z +1; print "$y $z\n"; }; }
        Result
        using exterior values 156 2 311 3 466 4 621 5 776 6 using localizing interior values 156 2 156 2 156 2 156 2 156 2

Re: Enlarging scalars
by hippo (Archbishop) on Jun 12, 2017 at 12:50 UTC

    Since what you have in the here doc looks suspiciously like XML, the right way to do it would be to leverage one of the XML modules such as XML::Twig or XML::LibXML.

    You could also do it with s/// but you would be making a rod for your own back.

    It turns out that it wasn't obvious what you wanted to do here after all. :-)

    The problem (which you haven't spelled out) is that the here doc interpolates when you set $a so your initial $y is never changed. One solution is not to interpolate but to use a placeholder scalar (which could just be "$y" again) and then eval the here document.

    #!/usr/bin/env perl use strict; use warnings; my ($y, $out); $y = 'baby'; my $hd = <<'EOT'; Hello $y! EOT eval "\$out = qq{$hd}"; print $out; $y = 'world'; eval "\$out = qq{$hd}"; print $out;

    But that's a bit crude. Far better to use a proper templating system.

Re: Enlarging scalars
by choroba (Cardinal) on Jun 12, 2017 at 13:46 UTC
    You can use a template to generate the XML from the two parameters, but in such a simple case, you can probably just declare a function that returns it and takes the two parameters:
    #! /usr/bin/perl use strict; use warnings; print "Hoeveel?\n"; my $hoeveel = <STDIN>; chomp $hoeveel; print "You typed: $hoeveel\n"; sub xml { my ($y, $z) = @_; return << "EOT"; <g transform="translate(-124.85653,$y)" id="layer$z"> <text xml:space="preserve" style="font-style:normal;font-variant:normal;font-weight:normal +;font-stretch:normal;font-size:126.0375061px;line-height:125%;font-fa +­mily:Arial;-inkscape-font-specification:'Arial, Normal';text-align:s +tart;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anch +or:start;fill:#000000;fill-opacity:1;stroke­:none;stroke-width:1px;st +roke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" x="-45.714272" y="235.21936" id="text3336"><tspan id="tspan3338" x="-45.714272" y="235.21936">a</tspan></text> </g> EOT } my $y = -931.96483; my $z = 1000; for (my $i=1; $i <= $hoeveel; $i++) { $y += 155; ++$z; print xml($y, $z); };

    huck's advice about not redeclaring the variables inside the loop holds.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      It's clearly SVG, and re-using the id values for the text and tspan elements may or may not cause trouble.
Re: Enlarging scalars
by marinersk (Priest) on Jun 13, 2017 at 03:58 UTC

    Hello, WisDomSeeKer34.

    It is obvious what I want to do here: I want to enlarge $y with 155 and $z with 1 by $hoeveel times. But how to do it?

    The solution seems obvious:

    $y += (155 * $hoeveel); $z += ( 1 * $hoeveel);

A reply falls below the community's threshold of quality. You may see it by logging in.