Fibonacci in Perl
So this is our fourth post of the Fibonacci project, and in this installment, we are going to take on Perl. For those of you who don’t know about the Fibonacci project, you should read the first post, Fibonacci in C. Also, you may want to check out the other posts in the series. The comments in the code will make more sense if you have seen the other examples.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
#!/usr/bin/perl # Functions in Perl are called subroutines. Like bash, you don't define the # parameters in the function declaration. We'll see how to access the parameters # when we look at the Fibonacci subroutine below. sub main { # Again, the ubiquitous printf function. Apparently a staple of programming printf "\nHow many numbers of the sequence would you like?\n"; # Once again, we don't need to declare variables before using them. # Perl's scalar variables, prefaced with $, can be either strings or numbers # We use <STDIN> to get the data from stdin here $n = <STDIN>; # As in PHP, we need to remove the newline at the end chop $n; &fibonacci($n); exit 0; } # Except for the first line declaring the subroutine, and the different way that # parameters passed to the subroutine are passed, this is identical to the PHP version sub fibonacci { $a = 0; $b = 1; # So now we see the parameter being used here. For clarity, I have written the for # loop using $n like the other examples. To set $n using the first parameter passed # to the subroutine, I access the scalar variable $_[0], which is the first element # of the parameter array @_ $n = $_[0]; for ($i=0;$i<$n;$i++){ printf "%d\n", $a; $sum = $a + $b; $a = $b; $b = $sum; } } &main; |
Any Perl gurus want to critique my work here? Like most of the examples, this is a simplified version, but one that works.
January 3rd, 2008 at 11:21 pm
hm, it seams part of my comment has been filtered out.
what I meant: i’ll substitute the “less than” sign with lt.
I really like what you’re doing here and think it’s a great idea, but you do use practically the same code everywhere. I’d like to see more language specific construct, for example, it’s not common to write
for ($i=0;$i lt $n; $i++)
but instead:
for(0…$n-1)
also, i think printf isn’t used as commen as normal print, you can just write
print “$a\n”; , variables get substituted in”‘s just like in php.
also: how about some golf:
++$b;for(0..lt>-1){print”$a\n”;($b)=($s,$a)=($a+$b,$b);}
works just as well 🙂 (remember to replace the “lt”
January 4th, 2008 at 1:29 am
Your Perl version runs fine, but you’ve got a number of conventions that, while not exactly wrong, are a bit dated (looks like you were
using a pretty old Perl tutorial/book/whatever). Here are some explanations followed by a more Perl-y bit of code:
– Scope your variables with ‘my’
$n = <STDIN> # $n here will be global which could end up being messy
my $n = <STDIN> # $n here is lexical – it falls out of scope at the end of the sub
– Use chomp() instead of chop(). chop() removes the last character from a string regardless of what the character is; chomp() only removes the last character if it’s a newline. This is a nice piece of idiot-proofing for those times when you’re absolutely 100% positive your string ends with a newline, but you are nonetheless wrong 😉
– Don’t use the & when calling a sub (unless you understand what the & does) – just include the parens at the end so the parser understands you’re making a sub call. Older Perl books/tutorials generally included the & on the front of a sub call, but it’s not necessary and can break things in ways you’re not expecting if you don’t do lots of Perl.
&fibonacci(5); # Generally considered bad, though it works and hurts nothing in your example
fibonacci(5); # works just fine, regardless of where you defined the sub
fibonacci(); # if your sub didn’t require any args, you just include empty parens
– The variables $a and $b are used by the builtin function sort(). You aren’t using sort() in your code, so in this case your $a and $b variables aren’t going to hurt anything, but it’s generally a good idea to get in the habit of staying away from those particular variable names – use $x and $y or whatever instead. If your code or any external code (a module or library) that you might be using uses sort anywhere and your code includes $a and $b, you can occasionally get hard-to-track-down bugs.
– In Perl, you can swap two variables’ values without using a temporary variable like so:
$a = ‘one’;
$b = ‘two’;
($a, $b) = ($b, $a);
print “$a — $b”; # ‘two — one’
– Last, your main sub isn’t necessary. Any code that isn’t wrapped in a sub becomes your program’s mainline. The little example below will run the first two lines of code even though they aren’t in a specifically named and called sub.
#################
my $var = mysub();
print “$var\n”;
sub mysub {
return ‘hi there’;
}
#################
– OK – putting it all together we get this:
#!/usr/bin/perl
print “How many numbers of the sequence would you like? “;
chomp( my $n = <STDIN> );
print “\n”; # Just to visually separate the user’s input from the program’s output
fibonacci($n);
sub fibonacci {
my $a = 0;
my $b = 1;
for( 0 .. ($_[0] – 1) ) {
print “$a\n”;
($a, $b) = ($b, ($a + $b));
}
}
January 4th, 2008 at 10:15 am
Simon and Tim,
Thanks! That’s exactly what I’m looking for. I’m going to update the post with a second version taken from the comments. It will definitely be more “perly.”
September 16th, 2011 at 10:02 pm
hm, it seams part of my comment has been filtered out.
what I meant: i’ll substitute the “less than” sign with lt.
March 29th, 2012 at 6:08 am
Agence Web en Tunisie…
[…]Fibonacci in Perl[…]…