Re: Problem creating a function
by jdporter (Paladin) on Dec 24, 2002 at 22:10 UTC
|
It's the definition of your function that's not quite right -- in particular, how you're defining and accessing the parameters.
If you don't mind changing the variable's contents (i.e. "destructive cleaning"), then
I would write the function like this:
sub cleaner {
$_[0] =~ s/\n/<br>/g;;
$_[0] =~ s/\t/ /g;
}
Then you can call it like this:
cleaner( $dirty );
and that will change the value of the variable in the way you want.
However, I'd point out that that is a pretty uncommon way to use subroutines, althought there's nothing wrong with it. (Do it this way if it's appropriate.)
If you want to get a cleaned version of a value, without changing the original, I'd write it like this:
sub cleaner {
local $_ = shift;
s/\n/<br>/g;;
s/\t/ /g;
$_
}
You can call this one like this:
$clean = cleaner( $dirty );
jdporter ...porque es dificil estar guapo y blanco. | [reply] [d/l] [select] |
|
|
| [reply] [d/l] [select] |
|
|
| [reply] [d/l] |
|
|
|
|
|
|
|
Re: Problem creating a function
by FamousLongAgo (Friar) on Dec 24, 2002 at 22:07 UTC
|
This is the proper syntax:
sub cleaner {
my ( $text ) = @_;
$text =~ s/\n/<br>/gs;
$text =~ s/\t/ /g;
return $text;
}
my $details = cleaner( $clean_me );
Note that function prototypes don't work in perl like in C or PHP code. You can't say sub cleaner( $dirty ) and expect the function to contain a variable called $dirty with your input parameter - you have to pull it off the magic @_ parameter array using shift or the syntax I use here.
Perl does have function prototypes of a sort, but they serve a different purpose than in other languages
Also, if you are matching newlines in your regular expression, you will need the s flag - otherwise the match will stop at the first newline. The s flag tells Perl to treat newlines like any other character, and match to the end of the string.
Update: See below for why that last piece of advice is irrelevant - thanks, jdporter!.
| [reply] [d/l] [select] |
|
|
| [reply] [d/l] [select] |
Re: Problem creating a function
by pg (Canon) on Dec 25, 2002 at 00:28 UTC
|
- I doute that your program can even 100% pass compiler. An old advice many good people have been giving from time to time: PLEASE USE perl -w.
In your case, if you use perl -w, you will see that, Perl actually takes your
sub cleaner($dirty)
as sub prototype, and warns you that there is illegal char in the prototype.
As I mentioned prototype, let's just give a simple example of how to use prototype. In the following example, if you uncomment the third call to greeting, you will get an error. Yes, the Perl prototype check is working, and it gives you an error "too many arguments".
use strict;
sub greeting($);
greeting("Merry Christmas");
greeting("Happy New Year");
#greeting("Merry Christtmas", "and Happy new Year");
sub greeting($) {
print "I say, \"", shift, "!\"\n";
}
- Also there is really no point, for you to make it looks like that you are passing a parameter to that function, when you are actually using it as a global variable. To learn more about Perl scope, could help you make the concept straight.
| [reply] [d/l] [select] |
Re: Problem creating a function
by bart (Canon) on Dec 25, 2002 at 10:56 UTC
|
cleaner(\$details); AND $details = cleaner($details);
my $dirty;
sub cleaner($dirty){
my $clean = ($dirty =~ s/\n/<br>/g;);
$clean =~ s/\t/ /g;
return $clean;
}
Perl doesn't work that way. Passing data through to a sub goes via @_, not via named arguments.
sub cleaner {
my($dirty) = @_;
...
}
And your other huge mistake is in this line:
my $clean = ($dirty =~ s/\n/<br>/g;);
Let's start by dropping the inner semicolon...
You assign the result of the s/// to $clean, which is the number of substitutions. Remember: s/// does an in-place substitution. The correct syntax for what you want is:
(my $clean = $dirty) =~ s/\n/<br>/g;
which first assigns the value of $dirty to $clean, and then the substitution takes place on the Lvalue, $clean. Cut into smaller peices, this does the same thing:
my $clean = $dirty;
$clean =~ s/\n/<br>/g;
All put together, you no longer need $dirty:
sub cleaner {
(my $clean = $_[0]) =~ s/\n/<br>/g;
$clean =~ s/\t/ /g;
return $clean;
}
$details = cleaner($details);
The code can still be further reduced to:
sub cleaner {
local $_ = shift;
s/\n/<br>/g;
s/\t/ /g;
return $_;
}
$details = cleaner($details);
| [reply] [d/l] [select] |
|
|
I realise that your just correcting the OP's code to make it work, but doesn't converting \n's to <BR>'s and then tabs to spaces strike you as a strange thing to do?
In as much as, one assumes that the results are destined for display in a browser, but the browser will discard both spaces and tabs, so the second step seems pointess.
Examine what is said, not who speaks.
| [reply] [d/l] |
|
|
Well BrowserUk, you would be correct if I was not working with a program that reads from a text file that's formated such that the paramaters are seperated by tabs, and the records by endlines. This program then takes the input from text file and displays to a browser, but I don't want to give you the impression that I'm heading down the wrong path to begin with.
bW
| [reply] |
|
|
|
|
| [reply] |