homepage Welcome to WebmasterWorld Guest from 54.145.209.80
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Pubcon Platinum Sponsor 2014
Home / Forums Index / Code, Content, and Presentation / Perl Server Side CGI Scripting
Forum Library, Charter, Moderators: coopster & jatar k & phranque

Perl Server Side CGI Scripting Forum

    
Sub Routine Ignorance
typomaniac



 
Msg#: 4322339 posted 1:11 am on Jun 6, 2011 (gmt 0)

I'm learning(however at a snail's pace). What I understand a sub routine is that it is for re-using code so as to prevent copy/paste/rewriting/etc.,. I've used them in a very limited way to this point but would really like to know a bit more about them. I've done lots of searching but always find explanations that I can't relate to for some reason---I'm not real smart bty.
As an example I have two scripts which basically use the same type of input but am using different input names for the values as they are separate scripts.

EXAMPLE:

#script a #scrip b
$a1="$username"; $b1="$username";
$a2="$userid"; $b2="$userid";
$a3="$submit_time"; $b3="$submit_time";

Seeing as $a1 and $b1 basically hold the same type of value, how would I send both scripts to the same sub without having to use something like:

sub example{
if($a1 eq ""){do something;}
if($b1 eq ""){do something;}
}

I guess what I'm asking is how does the sub know which script the input is coming from and return the processed values to it? Or, maybe what I'm trying to say is how could I write the sub like this:

sub example{
if($input1 eq ""){do something;}
}

with $input1 representing either $a1 or $b1 depending on the script that calls it and get the values returned to the appropriate script?

I hope I'm making sense of what I'm asking and not to confusing. I have 3 scripts which will all pretty much use the same input values and am just trying to eliminate all the extra code for doing the same thing.

 

janharders

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4322339 posted 6:44 am on Jun 6, 2011 (gmt 0)

First of all, you really should "use strict;" in your scripts. It'll make you work cleaner and keep typos from sending you on a long bug chase. See this article at perlmonks.org [perlmonks.org] why.

As for your question: you usually pass parameters into a sub routine, which are then available in the sub in the special array @_
for example:
print greet('My Name');

sub greet {
my $name = shift @_;
return 'Hello ' . $name;
}


All you need to worry about in your scripts is to pass in the right parameters and make sure they are in the right order.

phranque

WebmasterWorld Administrator phranque us a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month



 
Msg#: 4322339 posted 11:12 am on Jun 6, 2011 (gmt 0)

you might code your "example" subroutine like this:
sub example{
my $input1 = shift @_;
my $input2 = shift @_;
my $input3 = shift @_;
if($input1 eq ""){do something;}
}

and then pass variables to your "example" subroutine like this:
my $a1="$username";
my $a2="$userid";
my $a3="$submit_time";

example($a1$a2$a3);

rocknbil

WebmasterWorld Senior Member rocknbil us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4322339 posted 11:11 pm on Jun 6, 2011 (gmt 0)

FYI . . . the shift function shifts the first element off an array. Pop does the opposite, it pops the last element off the end of the array. An equivalent of phranque's example, allowing the array to remain an array without shifting . . .

sub example{
my ($result);
my ($input1,$input2,$input3) = @_;
if($input1 eq ""){ $result .= "We have nothing for input 1."; }
return $result;
}

Subs don't have to return values, it's just better coding if they do. It helps avoid odd bits of output appearing at the most inopportune times. You can also return arrays.

sub example{
my ($first,$second,$third);
my ($input1,$input2,$input3) = @_;
if($input1 eq ""){ $first = "We have nothing for input 1."; }
if($input2 eq ""){ $second = "We have nothing for input 2."; }
if($input3 eq ""){ $third = "We have nothing for input 3."; }
return ($first,$second,$third);
}

Or equivalently,

sub example{
my (@return);
my (@in) = @_;
if($in[0] eq ""){ $return[0] = "We have nothing for input 1."; }
if($in[1] eq ""){ $return[1] = "We have nothing for input 2."; }
if($in[2] eq ""){ $return[2] = "We have nothing for input 3."; }
return @in;
}

typomaniac



 
Msg#: 4322339 posted 12:37 am on Jun 7, 2011 (gmt 0)

Thaaaaaaaank you so much. I'm beginning to get a grasp on this one now...(notice I said a grasp). I'm going back to the text editor to do some experimenting. Hopefully I can seal the thread(hopefully). Your examples shed much light on the subject for me....but I'll probably have a few more questions on this before I'm done.

typomaniac



 
Msg#: 4322339 posted 12:15 pm on Jun 10, 2011 (gmt 0)

I began using strict as you suggested....lol, had to make a bunch of changes but if its for the better then so be it. One of the reasons I wasn't using strict was because the script I'm working on will need to be in two languages and found the easiest way was to use a .txt language file and list them as such:

$a=1;
$b=2;
etc.,

and then on the script page I was simply adding a

require"language.txt";

When I typed print"$a"; in the script whatever the text file had would appear but when I added strict nothing would appear unless the variable was declared and given a value. Any way to import variable values into a script using strict? If using strict is going to keep the code cleaner and the script running smoother I'm going to stick with it but curious.

typomaniac



 
Msg#: 4322339 posted 1:52 pm on Jun 10, 2011 (gmt 0)

My apologies, I should have been more specific. When I talked of using a language.txt or language.pl or whatever it would have to be to work I was referring to an external file. My reason for this there is the chance that I might have to expand to 3 languages....to be used on 3 different sites. I was thinking about making the language file easy to convert by using a form with the English text displayed along with a text block for what it will be changed to and using a replacement regex write the whole file with a click of the submit button once all the text blocks are filled in.

janharders

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4322339 posted 3:19 pm on Jun 10, 2011 (gmt 0)

No, you cannot include perl code like that and have it set variables any more, and there are better ways to solve that.
To keep it simple, I like just using a plain text file for languages, for example have one english.txt with
MSGID = message text
e.g.
ENTER_EMAIL = Please enter your email address
and have equivalent file for other languages.
Then, use something like
sub read_language_file {
my $file = shift;
die 'language file ' . $file . ' does not exist :(' . "\n" unless(-e $file);
my %language = ();
open(LANG, '<', $file) || die $!;
while(my $line = <LANG>) {
$line =~ s/\s+$//gs; # kill all whitespaces at the end of each line
next if(substr($line, 0, 1) eq '#' || $line eq ''); # allows to uncomment lines by putting # in the beginning
my ($key, $value) = split(/\s*=\s*/, $line, 2); # will match MSGID = text, MSGID=text etc
$language{$key} = $value;
}
close(LANG);
return %language;
}


in your code, call the function with a filename and it will return a language-hash.
my %text = read_language_file("english.txt");
print $text{"ENTER_EMAIL"};


That's a pretty basic way of dealing with that. Of course, it has weaknesses, for example it doesn't support placeholders, you cannot easily add singular/plural forms.
If you want to do that, look at Locale::Maketext [search.cpan.org] (great article about what it does and why [search.cpan.org])

typomaniac



 
Msg#: 4322339 posted 12:30 pm on Jun 11, 2011 (gmt 0)

Works great. I looked at the links you provided and "wow"--to me that is some heavy stuff for now but hopefully with study I can figure out whats going on. The only problems I had was having to use a single line for

print $text{'a'};

I can't put anything else on that line. Also, if I enter something like

print $text{'a'};
print $text{'b'};

The text from print $text{'a'}; and print $text{'b'}; is run together (no space between the values). I was able to work around this in a manner as such:

print $text["a"];
print"&nbsp;";
print $text["b"};

This put a space between the two printed values. Another way was to add html to the values in the language.txt page.

a=<li>List item</li>
b=&nbsp;&nbsp;2 empty spaces

This doesn't present a problem as I'm still able to format the text for the display page. I'm thinking for the extra few minutes involved it presents no problem but out of curiousity is this a normal way of going about this or do I need to learn some more(understatement of the year). Either way the system works great for me. THANX

janharders

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4322339 posted 4:18 pm on Jun 11, 2011 (gmt 0)

Well, I'd suggest you look into templating.
It's generally not a great idea to put output-logic like HTML inside your code. It's ok if your script / app is small and you're the only one working with it. But as soon as you have a design-person involved that needs to change the output but will probably break things if he / she edits the perl-script, you want a template.
I've worked with quite a few templating modules (including writing my own, a decade ago), but the Template Toolkit [template-toolkit.org] is where I remained for the last two years now. It's easy to get into and has quite a few possibilities if you need to get heavy.

But if you don't want to go that far, you can allways concat strings:
print $text{"a"} . " " . $text{"b"} . "\n";
Or just change the sub that reads the file and comment out ( put a # in the beginning ) the line that reads
$line =~ s/\s+$//gs;
thus, line endings will be present in the %text-hash, and I believe, in HTML they will be represented by spaces by the browsers.

typomaniac



 
Msg#: 4322339 posted 12:11 pm on Jun 12, 2011 (gmt 0)

Problem pretty much taken care of and many many thanx to you. I am pondering/looking into templating. As far as a design-person...I hope he loves spaghetti although I have to say that thanks to you people here I have really cut the serving size----eliminated many noodles and much runny sauce. I'm getting there. Thanks again, again, etc.,.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Perl Server Side CGI Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved