Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Printing multiline 2

Status
Not open for further replies.

rvBasic

Programmer
Oct 22, 2000
414
BE
Writing to an error log, I used following construct:
Code:
#separate print statements
print "first line\n";
print "second line\n";
print "third line\n";
print "\n";
It then occured to me that I called the print function 4 times and that it would probably be more performant to use
Code:
#Single print - single line
print "first line\nsecond line\nthirdline \n\n";
which indeed produced the same output:
Code:
first line
second line
third line
Unfortunately, informative error messages tend to be longer and using the single print option quickly ran into code readability problems, due to extremely long progam statements. So I decided to break up the line in different chunks, terminating each previous line with the Enter key.
Code:
#Single print - multiline - Enter
print "first line\n
second line\n
third line\n
\n";
Which much to my (initial) surprise produced - double spacing!
Code:
first line

second line

third line
Therefore I removed the newline character from my statements to finally settled on this:
Code:
#Single print - multiline - Enter
print "first line
second line
third line
\n";
Giving the single spaced result.

Is this a correct way of producing single spaced multilines?

_________________________________
In theory, there is no difference between theory and practice. In practice, there is. [attributed to Yogi Berra]
 
Hey, thats strange,

I have never been able to get spaces between lines based on how they are positioned in the script.

Personally I find the neatest way is to simply use

print "line 1\n";
print "line 2\n";
print "line 3\n";

and use \n\n for double spaces.

So long as it works for you, there isn't really an issue how you do it.

Chris
 
There are many ways of doing that, none of which are "standard", as such. For large blocks of code, there's heredocs:
Code:
print <<EndText;
line 1
line 2
line 3
EndText

If it's a few lines you're printing, the following is IMO neater than multiple print statements:
Code:
print "line 1\n",
  "line 2\n",
  "line 3\n";
 
I prefer q and qq

Code:
print q{line with no variables
line with no variables
};

print qq{line with $vars
line with $vars
};

but even simple double-quotes or single-quotes will work:

Code:
print 'line with no variables
line with no variables
';

print "line with $vars
line with $vars
";

but then you have to manually escape embedded quotes, which q and qq do for you automatically. All of perls string constructors preserve formatting when used for printing data. You do not have to manually add a newline character at the end if there is one like in the above examples.

but I am also unsure if any of the examples show are any more efficient than using multiple print lines.



------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
I also favor the use of q and qq for string identifiers:

Code:
[gray][i]# Non-interpolated[/i][/gray]
[url=http://perldoc.perl.org/functions/print.html][black][b]print[/b][/black][/url] [red]q{[/red][purple]line 1[/purple]
[purple]line 2[/purple]
[purple]line 3[/purple]
[purple][/purple][red]}[/red][red];[/red]

[gray][i]# Interpolated[/i][/gray]
[black][b]print[/b][/black] [red]qq{[/red][purple]line 1[/purple]
[purple]line 2[/purple]
[purple]line 3[/purple]
[purple][/purple][red]}[/red][red];[/red]

However, there are times when heredocs are better in my opinion. If you choose to use them though, I strongly advise you to always enclose the identifier in either double or single quotes to indicate whether you want interpolation. The default is to interpolate, but not everyone remembers this. So to be safe always explicitly write out your intention:

Code:
[gray][i]# Non-interpolated[/i][/gray]
[url=http://perldoc.perl.org/functions/print.html][black][b]print[/b][/black][/url] [red]<<'END_TEXT'[/red][red];[/red]
[purple]line 1[/purple]
[purple]line 2[/purple]
[purple]line 3[/purple]
[red]END_TEXT[/red]

[gray][i]# Interpolated[/i][/gray]
[black][b]print[/b][/black] [red]<<"END_TEXT"[/red][red];[/red]
[purple]line 1[/purple]
[purple]line 2[/purple]
[purple]line 3[/purple]
[red]END_TEXT[/red]

- Miller
 
I like to use qq too, but since qq can be used with a handful of delimiting characters (curly {} brackets being one of them), I prefer to use the tilde ~

Code:
print qq~
line 1
line 2
line 3
~;

It's especially good for CGI when you're printing a lot of HTML code which may include CSS and JavaScript. If you use the qq{} with the curly brackets, you need to escape every curly bracket in your code, i.e.

Code:
print qq{
<style type="text/css">
body \{
   background-color: #FFFFFF
\}
a:link \{
   color: #0000FF
\}
</style>
};

And that's a lot of extra work on the programming side cuz there's two fairly frequent characters that need to be escaped. Whereas, if you do it with tildes:

Code:
print qq~
<style type="text/css">
body {
   background-color: #FFFFFF
}
a:link {
   color: #0000FF
}
</style>
~;

You will rarely need to escape anything at all in your text (except for things like $ and @, naturally), and the tilde itself is very rarely used in a web page, or anywhere at all.

Plus, its easy to remember: use a ~ to start the qq and a ~ to end it, instead of keeping track of which direction your brackets are facing.

-------------
Cuvou.com | My personal homepage
Project Fearless | My web blog
 
Nope, this works just fine without escaping the curly brackets:

Code:
print qq{
<style type="text/css">
body {
   background-color: #FFFFFF
}
a:link {
   color: #0000FF
}
</style>
};

When you use matched pairs like {} or [] for the delimiters, perl counts them in and out of the string. You only have to escape it if they are not used in equal number within the string. Like this example:

Code:
print qq{
<style type="text/css">
body {
   background-color: #FFFFFF
}
a:link {
   color: #0000FF
}
</style>
}
};

When you use a single character like a tilde then you always have to escape them in the string.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Yes, I second what Kevin said about balanced braces.

In 7 years of coding, I've only come by one time where I actually needed to escape a bracket enclosed in a qq{} string. Meanwhile, there have been at least a dozen times where the fact that perl counts brackets actually detected an error in my enclosed javascript or style sheet code. I therefore strongly encourage you to use qq{}, although I do know some other programmers that do favor the tilda encapsulator, for whatever reason.

- Miller
 
Thanks to all who did reply to such a simple question. Let me first clarify that in this application I have to interpolate.

As most were in favour of the qq solution, I tried this:
Code:
#Single print - multiline - single qq
print qq{first line
second line
third line
\n
};
which my friendly source formatter promptly improved to:
Code:
#Single print - multiline - single qq
print qq{first line
	second line
	third line
	\n
};
with the resulting
Code:
first line
	second line
	third line
I therefore switched to:
Code:
#Single print - multiline - multiple qq
print qq{first line\n},
qq{second line\n},
qq{third line\n},
qq{\n};
to get the desired result with certainty(?). Which squared the circle: I got rid of the multiple print statements but at the expense of multiple qq constructs. Did I gain anything? I don't kno, as I perceive no performance difference (I didn't measure it)

I settled on a variation of ishnid's suggestion:
Code:
#Single print - multiline - concatenation
print "first line\n"
    . "second line\n"
    . "third line\n\n";

But, may be, the multiple print apprach was not too bad after all[ponder]






_________________________________
In theory, there is no difference between theory and practice. In practice, there is. [attributed to Yogi Berra]
 
kill the source formatter. It's not so friendly after all if it can't recognize valid perl strings, and tries to insert tabs in them.

If you want a perl formatter, stick with Perl Tidy.

- Miller
 
I notice you're now concatenating your lines before sending them to print. You should know that that approach is less efficient than the code I posted whereby the print function is given a list of strings it doesn't have to concatenate (the list being created by the comma operator).
 
You should have just rejected the formatter and stuck with:

Code:
#Single print - multiline - single qq
print qq{first line
second line
third line
\n
};

although I am not sure why you put a newline on the end like that. That will result in two newlines being added at the end, maybe that is what you want?

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
ishnid Good reference, I'll switch to your suggestion.

KevinADC ...I am not sure why you put a newline on the end like that. That will result in two newlines being added at the end, maybe that is what you want? There must be some confusion now: my first example (in the second post) copies exactly your lines of code. This is were the code formatter kicked in and produced the indentation. Therefore I switched to the qq list format but there I had to add the new line character at the end of each element in the list. And no, I don't want two newlines.

KevinADC,MillerH You both seems to kill the source formatter, but then you two do produce nicely structured sample code. How do you do it? Pure discipline? What are the arguments against using formatters? (BTW my environment is Win32, Eclipse, EPIC which does use PerlTidy)

_________________________________
In theory, there is no difference between theory and practice. In practice, there is. [attributed to Yogi Berra]
 
Sorry KevinADC I think, I understand your comment now [smile] The two newlines at the end of the last line are needed as I want to separate one error message from the previous one in the error log.

_________________________________
In theory, there is no difference between theory and practice. In practice, there is. [attributed to Yogi Berra]
 
Maybe if I was writing a large script I would run it through a formatter, but I would also double-check for unintentional consequences of using a formatter, like formatting a print block that messes up what/how you intended to print output.

For me, formatting code as I write it is a habit.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
In general, I have nothing against code formatters and think they're quite useful (particularly in a collaborative environment where everyone can write in their own style and apply the standard group-approved style automatically afterwards). However, I do not consider it to be acceptable that a formatter would change what my code actually does. I spend enough time fixing bugs I've introduced myself :)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top