tag:blogger.com,1999:blog-59076556058071226322024-03-19T02:17:41.384-07:00Perl AdventuresAnonymoushttp://www.blogger.com/profile/14422352024976746995noreply@blogger.comBlogger15125tag:blogger.com,1999:blog-5907655605807122632.post-3237885618305744882014-05-30T01:51:00.003-07:002014-05-30T01:51:53.310-07:00Loops and conditionals: Control your loopI've used loop controls once and I can't remember why, but I know it was useful...<br />
<br />
Loop controls, as it indicates in the name, give you more control over the flow of a loop. Without them, you just have to accept the way that for, if, while etc. loops function and work around them to serve your purpose. With them, you can modify the way a loop works, for example you might want to jump out of a loop completely for reasons other than the initial condition not being satisfied.<br />
<br />
There are three loop control operators:<br />
<br />
<b>Last</b><br />
<b>Next</b><br />
<b>Redo</b><br />
<b><br /></b>
These operators can be applied to the five kinds of loops there are in Perl:<br />
<ul>
<li>for</li>
<li>foreach</li>
<li>while</li>
<li>until</li>
<li>naked block</li>
</ul>
<div>
<b>NB</b> You can't apply them to an if statement because it's not a loop and it really won't make sense, the code blocks in if statements are only run zero times or once. </div>
<div>
<br /></div>
<div>
Wait, what is this naked block thing? It sounds kind of weird...<br />
<br />
This block is naked! It has nothing in front of its curly braces :-o<br />
<br />
{<br />
code goes here<br />
}<br />
<br />
A naked block is just a block of code surrounded by curly braces, with no keyword or condition. It runs only once, as if the curly braces weren't there so in my opinion, it's not really a loop. You might wonder what the point is of putting curly braces around code. They can be useful if you want to have a variable that is only in scope in part of the code because the guideline is to declare a variable in the smallest scope available.</div>
<br />
Here's how the loop control operators work:<br />
<b><br /></b>
<b><u>Last</u></b><br />
This operator immediately ends execution and breaks out of the loop, no more iterations happen, even if you haven't finished going through all the elements in the array or the condition still evaluates to true etc.<br />
<br />
If you're used to how perl works, it may look a bit strange in the code below because it's a <b>bareword</b> (i.e. has no prefix or suffix, or sigil, it's just a word on it's own). Barewords usually aren't allowed but there are a few key words, including the loop control words, that are. If you try to type in a bareword that isn't one of these key words, you will be complained at.<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>foreach(@myarray) {</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td> <b style="font-family: Arial, Helvetica, sans-serif;">if( $_ eq "end") {</b></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> last;</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td> <span style="font-family: Arial, Helvetica, sans-serif;"><b>else {</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">5.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "$_\n";</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">6.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> }</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">7.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
This code goes through the array called myarray and prints out each element until it gets to an element that is the string "end". End will not be printed and the loop will stop, no further elements will be printed.<br />
<br />
<br />
<b><u>Next</u></b><br />
This operator is used when you want to jump out of the current iteration but you then want the next iteration to continue afterwards. When next is hit, it jumps to the end of inside the current loop (at the closing curly bracket) and then the next iteration starts.<br />
I've nicked this example straight from "Learning Perl" by Randal Schwartz so thanks people that wrote it :-)<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>while (<STDIN>) {</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td> <span style="font-family: Arial, Helvetica, sans-serif;"><b>foreach my $word (split(' ', <STDIN>)) {</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> $total++;</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td> <span style="font-family: Arial, Helvetica, sans-serif;"><b>next if /\W/;</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">5.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> $valid++;</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">6.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> }</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">7.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
The code above basically looks at words in a file and counts how many words in total there are and of these, how many are real words. Here is a mored detailed explanation if you'd like to know more:<br />
<br />
Lines of input are being read one at a time through <STDIN>. The split function splits the line up using spaces so individual words will be looked at. Then for each of the words in the line, the count of words is upped one ($total) and then on line 4, the word is looked at to see if it contains any non-word characters (anything but letters, numbers and underscores) This is done by /\W/ where 'W' matches any non-word character. If the word contains any non-word characters, next is invoked, the iteration exits and the next word is looked at. If the word doesn't contain any non-word characters, the valid count will be incremented.<br />
Hope that makes sense!<br />
<br />
You may have noticed I've sneakily glossed over a few things like how the input is being taken from <STDIN> but just trust me (and the people that wrote the example) for the moment, that it works and does what it's supposed to.<br />
<b><br /></b>
<b><u>Redo</u></b><br />
This operator means go back to the beginning of the iteration you are currently in and do it again, without testing the condition. Why would we need this? Here's an example, again, curtesy of "Learning Perl", but slightly modified - thanks guys!<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @words = qw( accommodate believe colleague disappear embarrass);</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my $errors = 0;</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><br /></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>foreach my $word (@words) {</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">5.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "Type the word '$word': ";</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">6.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>chomp(my $try = <STDIN>);</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">7.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>if ($try ne $word) {</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">8.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "Sorry - that's not right.\n";</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">9.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> $errors++;</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">10.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> redo;</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">11.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> }</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">12.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">13.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>print "You completed the test with $errors errors.\n";</b></span></td></tr>
</tbody></table>
</blockquote>
Ok so what does this mean? It's basically a spelling test and you have to keep writing the words in the @words array until you spell them correctly. It's not the best spelling test in the world because you are shown the word you need to type, but you get the idea.<br />
<br />
So, for each of the words in the words array, the command line will display a prompt for the user to type in the word. Then line 6 uses the chomp operator, which cuts off any newline characters from the end of the word that the user has typed in (this is from pressing enter to submit the word they have spelt). The user input is assigned to $try. Then $try is compared to the correct version of the word from @words on line 7. If the word is spelt correctly, the next iteration begins, giving the user a new word to spell. If they have spelt it wrong however, the terminal asks them to spell it again, then adds one to the error count and on line 10, redo tells the programme to do the iteration again.<br />
<br />
<br />
All of the above examples contain nested loops and the inner one is always an if statement. I'm trying to think of examples where you use a loop control operator without a nested if statement and I'm not sure if they would work without one. Please let me know if you have any examples.<br />
<br />
<br />
<b><u>Labelling Blocks</u></b><br />
<b><br /></b>Labels are very helpful, they can actually control where you will be taken next. They also allow anyone else reading your code - or even yourself if you've forgotten - to see clearly what is going on.<br />
<br />
Sometimes you will be nesting loops and blocks of code inside of each other and it can be hard to figure out where the loop controls will take you next. You can use labels to help with this, especially when you want to work with a loop block that's not the innermost one.<br />
<br />
I've also been told that it's best practise to use labels even if you think it's easy to follow where the loop will go. This may be true for you but you need to bear in mind that other people may look at your code and not understand or this loop could eventually be expanded and adding a label now will make it clearer for the future.<br />
<br />
Labels are another example of a bareword and they are named like any other identifier in perl; they can include letters, digits and underscores, but can't start with a digit. Larry Wall has actually recommended that labels are all upper case and this is what I've come across in real-world code so far. Perl is case sensitive and having an uppercase label will avoid having a label with the same name as a built-in function or even one of your own subroutines.<br />
<br />
To add a label, first you define the block of code that you want to label by writing the label name, followed by a colon, followed by the loop:<br />
<br />
<b>ELEMENT:</b> foreach (condition) {<br />
code block<br />
}<br />
<br />
This has labelled the whole foreach loop as "ELEMENT", (not just the line) and it includes everything inside the curly braces, as well as the foreach statement. After labelling your loop, then you decide which of the operators you are going to use and where in the code block you are going to put it.<br />
This example is curtesy of Andrew Solomon, who has taught me a lot about perl and taught me about loop labels.<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>sub pick_random_colour { 'purple' };</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my %betters = (</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> amy => [qw/green/],</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td> <span style="font-family: Arial, Helvetica, sans-serif;"><b>ben => [qw/ blue purple yellow/],</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">5.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> chloe => [qw/red orange pink/],</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">6.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>);</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">7.</span></td>
<td><br /></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">8.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my $win = pick_random_colour();</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">9.</span></td>
<td><br /></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">10.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>HOORAY: foreach my $better (sort(keys(%betters))) {</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">11.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> foreach my $ticket (@{$betters{$better}}) {</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">12.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> if ($ticket eq $win) {</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">13.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "Hooray! $better wins with $ticket\n";</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">14.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> last HOORAY;</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">15.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> }</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">16.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "Nope, $better has no luck with $ticket\n";</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">17.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> }</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">18.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
Ok, this is my largest example so far, but I think it really shows how labels work. Try it for yourself, run it, then take the label out, and then run it again and see the difference. Or you can look below and see the results:<br />
<br />
<b>With labels:</b><br />
Nope, Amy has no luck with green<br />
Nope, Ben has no luck with blue<br />
Hooray! Ben wins with purple<br />
<br />
<b>Without labels:</b><br />
Nope, Amy has no luck with green<br />
Nope, Ben has no luck with blue<br />
Hooray! Ben wins with purple<br />
Nope, Chloe has no luck with red<br />
Nope, Chloe has no luck with orange<br />
Nope, Chloe has no luck with pink<br />
<br />
Notice Ben has no luck with yellow is not printed out.<br />
<br />
The basic gist of this example is kind of like a lottery where each person can buy a ticket with a unique colour on it. Amy has bought one ticket (green) and Ben and Chloe have bought three tickets each (blue purple and yellow and red, orange and pink respectively). A random colour is picked and the winner is the one with the matching ticket.<br />
I've hacked it a little bit and written the pick_random_colour subroutine so that purple is always picked instead of a random colour. This is just so I can be certain of the outcome each time and can really see the difference when I take the labels out.<br />
<br />
So here is the full breakdown, again, skip this if you feel you understand the example already.<br />
Line 1, this is where my pick_random_colour subroutine is written that picks purple every time. I'll explain subroutines in more detail in a later post but for now, they are just pieces of code written in one place and called in another. You can see it being called on line 8. I've then declared an array, %betters, and assigned it names as keys and different lottery tickets as bets, each with a different, unique colour. Then the pick_random_colour subroutine is called on line 8 and of course, it's going to pick "purple". Now comes the exciting bit - the loop. So, we've got for each better in the hash and then for each ticket the better has, the ticket is compared to $win, which is purple. I've used sort on line 10 just so that the betters will be looked at in the same order each time. If the ticket is equal to purple, then the string on line 13 is printed and then we get to line 14 with the loop control and label. This indicates that we should cut out of the inner loop as well as the loop that is labelled with "HOORAY". This means that the program has finished. If the ticket is not equal to purple, the string on line 16 will be printed and the search will continue as to who has the winning ticket.<br />
If we take out the labels, but leave in the loop control, only the inner loop will be exited when the winner is found and the next better will be looked at. You can see from the results above that once the winning ticket from Ben has been found, Ben's remaining tickets are not looked at, but then Chloe's tickets are looked at.<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/14422352024976746995noreply@blogger.com4tag:blogger.com,1999:blog-5907655605807122632.post-92218916437718854552014-04-23T07:49:00.001-07:002014-04-23T08:59:01.170-07:00Loops and conditionals: While/untilThis is going to be simple little post about the while statement. It's general format looks like this:<br />
<br />
<b>while </b>(condition) {<br />
code block<br />
}<br />
<br />
As you can probably figure out, the code block is executed while the condition evaluates to true. As soon as the condition evaluates to false, the code block is passed over and the rest of the file is run. The conditions function exactly the same way as I wrote about in my if post, so if you need to brush up on what a condition is and how it works, go to http://www.perladventures.blogspot.co.uk/2014/04/ifelsifelse.html<br />
<br />
Here's an example of how you can use while in your code:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my $i = 5;</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><br /></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>while ($i > 0) {</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td> <span style="font-family: Arial, Helvetica, sans-serif;"><b>print "</b></span><b><span style="font-family: Arial, Helvetica, sans-serif;">$i\n";</span></b></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">5.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> $i--;</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">6.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
This will give output:<br />
5<br />
4<br />
3<br />
2<br />
1<br />
<br />
The condition is evaluated before the first iteration so if the condition is initially false, the code block will never be run.<br />
<br />
<b>Until</b><br />
<br />
There's also a revers version of while. I've never actually seen it in real code before and it looks just as difficult as unless.<br />
<br />
<b>until </b>(condition) {<br />
code block<br />
}<br />
<br />
This time, the code black runs while the condition evaluates to false<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my $i = 1;</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my $j = 12;</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><br /></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>until ($i > $j) {</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">5.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> </b></span><b style="font-family: Arial, Helvetica, sans-serif;">print "$i\n";</b></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">6.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> </b></span><b style="font-family: Arial, Helvetica, sans-serif;">$i *= 2;</b></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">7.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
This will give output:<br />
1<br />
2<br />
4<br />
8<br />
<br />
Again, the condition is evaluated before the code block is run. So if your condition initially evaluates to true, the code block will never be run.<br />
<br />
The examples I've done are all to do with numbers but you can use pretty much anything you want.<br />
<br />
Next in the loops and conditionals mini-series - loop controlsAnonymoushttp://www.blogger.com/profile/14422352024976746995noreply@blogger.com1tag:blogger.com,1999:blog-5907655605807122632.post-81550940892082947172014-04-10T07:10:00.000-07:002014-04-16T01:27:14.791-07:00Loops and conditionals: For eachArrays and lists and things like that are all very well, but we often need a way of going through each element sequentially to make use out of them - maybe to search for something or to do some function on each element. This is where for and foreach loops come in.<br />
<br />
A for(each) loop goes through each item in an array or a list or anything else you want to iterate through for example numbers 1-10. In fact, if the thing you put inside the brackets returns a list, it can be iterated over.<br />
<br />
It's general layout looks something like this:<br />
<br />
<b>for(each)</b> (array/list/whatever) {<br />
code block<br />
}<br />
<br />
<b>For or foreach?</b><br />
I've just discovered that for and foreach are completely identical and do exactly the same thing. You can use them both interchangeably. The underlying code for both is exactly the same. This leads me to think why then, are there two different words for it, but unfortunately I don't think there is a real answer to it.<br />
I wanted to find out which one programmers prefer and I asked around at work and it seems like the only reason they pick one over the other is convention. Most of the people I asked use for and foreach in the following way:<br />
<br />
<b>For</b> is generally used if you don't have something specific to iterate through. You can <span style="background-color: white;">initialise a variable, condition check and increment the variable.</span><br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>for (<span style="color: red;">my $i = 1</span>; <span style="color: purple;">$i < 9</span>; <span style="color: blue;">$i++</span>) {</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "$i "</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
This just prints out numbers 1 to 8 with a space between each.<br />
<br />
For those who are unfamiliar with the above -<br />
<span style="color: red; font-family: Arial, Helvetica, sans-serif; font-weight: bold;">my $i = 1 </span><span style="font-family: Times, Times New Roman, serif;">- initialising the variable to use.</span><br />
<b style="font-family: Arial, Helvetica, sans-serif;"><span style="color: purple;">$i < 9 </span></b><span style="font-family: Times, Times New Roman, serif;">- giving the variable a maximum or minimum size.</span><br />
<b style="font-family: Arial, Helvetica, sans-serif;"><span style="color: blue;">$i++ </span></b><span style="font-family: Times, Times New Roman, serif;">- showing how much to increment or decrement the variable with each pass of the loop - in this case, it means plus one.</span><br />
<br />
<span style="font-family: Times, Times New Roman, serif;">Basically all of this put together means, there is a variable called $i with a value of one. Start with $i = 1 in the first pass of the loop and add one to it each time you go through the loop until $i is no longer less than 9, then exit the loop.</span><br />
<br />
<br />
<b>Foreach</b> is often used if you are going through an array or list or hash and you want to go through the elements of each one. For example:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>foreach (@myarray) {</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "$_\n";</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
This just goes through each item in the array and prints them out on individual lines.<br />
<br />
You can however, swap the for and foreach around or you can use the same word for both usages, it's totally up to you but I think I'm going to stick with how I've described it as above.<br />
<br />
The good thing about foreach loops in perl, which I haven't come across before, is that you don't have to explicitly say how big the array or whatever you're iterating through is and you don't have to tell it that you want to go to the next item once it's finished with the item it's on.<br />
<br />
<b>What is this $_?</b><br />
In this case, it is a quick and anonymous way of referring to each individual item of the array, it's called the "default" variable. It represents the scalar that's being focussed on so in the case of a for loop, it's the list item or array item that's being currently looked at. It's kind of like using the word "it" in the English language - you know what you are referring to, but you're using a general word.<br />
<br />
It is bad practice to directly alter the original array so instead you can assign the individual elements to a new variable as I've done below - $item refers to each individual array item:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>foreach my $item (@myarray) {</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "$item\n";</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
You can also use foreach with hashes, it's very similar to arrays:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>foreach my $key (keys %myhash) {</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "this is the key: $key\n";</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "this is the value: ".$myhash{$key}."\n";</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
This will print out the statements followed by the key on one line and the value on the next for each of the items in the hash.<br />
Note the "my" isn't completely necessary, because if you leave it out, the "my" will be implied anyway.<br />
<br />
You need to write the word "key" inside the brackets before writing the name of the hash because what you are doing is getting a list of keys in the hash and then iterating over them. Within the code block, you can then use the key to get the values.<br />
<br />
I then wondered about not just getting a list of the keys and iterating over them, but getting the keys and the values and iterating over them and I was told about "each". You can't really use it with a for loop and it looks something like this:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>while (my ($key, $value) = each %hash) {</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "key is $key, value is $value\n";</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
As you can see you use a while loop, which I haven't covered yet but basically it just goes through all of the keys and values and prints them out.<br />
A warning does come with using each - you need to make sure that nothing else in your program can is changing the hash you're iterating over because if changes happen during the while loop. You may end up skipping or duplicating entries.<br />
<b><br /></b>
<b>Map</b><br />
I think I have mentioned map before but this is definitely a place to write a reminder. It's just a slightly cleaner way of writing code that takes each member of an array/list and modifies or uses it in the same way to create a new list.<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @new_array = map {</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "this is the key: \n";</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "this is the value: $item \n"</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
Anonymoushttp://www.blogger.com/profile/14422352024976746995noreply@blogger.com5tag:blogger.com,1999:blog-5907655605807122632.post-64764295089670109562014-04-03T03:23:00.003-07:002014-04-16T01:26:55.035-07:00Loops and conditionals: IfelsifelseThe next things on my list are conditionals and loops. I think that these concepts are fundamental to actually making any programming language work and without them, there wouldn't be much to do, especially when combined with conditional logic.<br />
<br />
The first one is the <b>if statement</b>. It's basic structure is something like this:<br />
<br />
<b>if </b>(condition) {<br />
code block<br />
}<br />
<br />
This evaluates the condition in the parentheses, and if it's true, the code block will be run and if it's false, the code block will be passed over and the rest of the file will be run.<br />
<br />
<b>Boolean Logic</b><br />
<br />
How do I make the condition equal to true or false?<br />
Perl doesn't actually have any specific true or false objects or identifiers so we have to make the condition evaluate to values that themselves are either true or false.<br />
<br />
What evaluates to true or false?<br />
Basically everything is true, apart from undef, "0", an empty string ("") and anything that evaluates to any of these.<br />
<br />
The table below shows how you can get true or false values:<br />
<br />
<table border="1" cellpadding="5">
<tbody>
<tr>
<td><b>True</b></td>
<td><b>False</b></td>
</tr>
<tr>
<td>"0.0"</td>
<td>""</td>
</tr>
<tr>
<td>" "</td>
<td>"0"</td>
</tr>
<tr>
<td>1</td>
<td>undef</td>
</tr>
<tr>
<td>+ve integers</td>
<td>0 # converts to "0"</td></tr>
<tr>
<td>-ve integers</td>
<td>0.0 #computes to 0 and then converts to "0"</td></tr>
<tr>
<td>strings</td>
<td>unassigned variable #evaluates to undef</td></tr>
<tr>
<td><br /></td>
<td>() #empty list</td></tr>
<tr>
<td><br /></td>
<td>("") #empty string in a list</td></tr>
</tbody></table>
<br />
You can put any of these as the condition, for example:<br />
<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>if (7) {</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> code block</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my $value = 0.0;</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>if ($value) {</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> code block</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
<b><br /></b>
The code block will run in the first example because 7 is a positive integer and positive integers evaluate to true. The code block will not run in the second example because 0.0 evaluates to false.<br />
<br />
You don't have to put single values into the condition - you can also use boolean operators to make things more interesting and with these, you can make expressions that evaluate to true or false.<br />
<br />
<br />
<table border="1" cellpadding="5">
<tbody>
<tr>
<td><b>Boolean Operators</b></td>
<td><b>Meaning</b></td>
</tr>
<tr>
<td>></td>
<td>Greater than (numerical)</td>
</tr>
<tr>
<td><</td>
<td>Less than (numerical)</td>
</tr>
<tr>
<td>==</td>
<td>Equal to (numerical)</td>
</tr>
<tr>
<td>gt</td>
<td>Greater than (string)</td>
</tr>
<tr>
<td>lt</td>
<td>Less than (string)</td>
</tr>
<tr>
<td>eq</td>
<td>Equal to (string)</td>
</tr>
<tr>
<td>!</td>
<td>Not</td></tr>
<tr>
<td>&&</td>
<td>And</td></tr>
<tr>
<td>||</td>
<td>Or</td></tr>
</tbody></table>
<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my $temperature = 28;</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>if ($temperature > 25) {</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "it's hot!";</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my $value = 4;</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>if ($value < 8 && $value > 5) {</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "this number is between 5 and 8";</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my $string = "hello";</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>if ( ($string eq "hello") || ($string eq "hi") {</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "hello there";</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
<br />
Of course you can put more interesting things inside the code blocks than just a print statement, but you get the idea.<br />
<br />
You can also experiment with making things more complicated and incorporate as many ands and ors as you want and and combination of boolean operators or do crazy things like XOR and NAND.<br />
<br />
To use not, you just put the exclamation mark in front of the expression you want to evaluate:<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;"><b>(!($string eq "hello"))</b></span></blockquote>
I think the inside brackets are optional but it makes things clearer and shows that you want to negate the whole of the expression rather than just the variable.<br />
<br />
<b>Note</b><br />
If you try to compare two numbers using the string equal to operator (eq) the numbers will be stringified and then compared. If your two numbers are the same, the condition will evaluate to true as the strings will be the same. If the numbers are different, you will get false.<br />
<br />
If you try to compare two strings using the numerical equal to operator (==) you will get warnings but it will always evaluate to true, even if the strings are not the same. This is because strings are evaluated as 1 and then you will be comparing two 1's.<br />
<br />
<div>
<b>Else</b></div>
<div>
<b><br /></b>
Sometimes you want something to happen if the if condition isn't satisfied. You can then add extra code to say what you want to do if the if condition evaluates to false by using else. The else immediately follows the if as follows:<br />
<br />
<b>if</b> (condition) {<br />
code block<br />
}<br />
<b>else</b> {<br />
code block<br />
}<br />
<br />
This way some code will always be run no matter what the condition evaluates to. If it evaluates to true, only the first code block is run, if it evaluates to false, only the second code block is run. Then the rest of the file is then run as normal.<br />
<br />
This example could work in a shop selling alcohol (can you tell I used to work in a supermarket?):<br />
<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>if ($customer_age > 17 {</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "sale authorised";</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>else {</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">5.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "sale denied";</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">6.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
<b><br /></b></div>
<div>
<b>Elsif</b></div>
<div>
<b><br /></b>
What happens if you want to put multiple ifs together? Say that you want to test one condition, and if it's not satisfied, you want to test another condition. This is where elsif comes in, and for reasons unknown to me, it is spelt with a missing 'e'. Excellent.<br />
<br />
<b>if</b> (condition) {<br />
code block<br />
}<br />
<b>elsif</b> (condition) {<br />
code block<br />
}<br />
<br />
If neither of the conditions are satisfied, neither of the code blocks will be run. If the first and the second condition are satisfied, only the first code block will be run because the second conditions is only evaluated if the first condition is not true.<br />
<br />
For example:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my $x = 50;</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @small_numbers;</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @medium_numbers;</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><br /></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">5.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>if ($x < 101) {</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">6.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> push(@small_numbers, $x)</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">7.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>} elsif ($x < 201) {</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">8.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> push(@medium_numbers, $x)</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">9.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
<br />
This code is just looking at the number and putting it into an array of small or medium numbers. So here I've defined small as 100 or less and medium as 200 or less. If the number is larger than 200, nothing will happen. I know this makes no sense in the real world but I think it works as an example.<br />
<br />
You can write it like this or you can add an "else" onto the end if neither of the two conditions are satisfied.<br />
<b><br /></b>
You can chain as many elsifs as you want together but only on else can be put onto the end.<br />
<br />
I couldn't think of a real life example so, again, here are a bunch of numbers:<br />
<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my $x = 5;</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @small_numbers; </b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><b style="font-family: Arial, Helvetica, sans-serif;">my @medium_numbers;</b></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @large_numbers;</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">5.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my <complete id="goog_389966223">@very_large_numbers;</complete></b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">6.</span></td>
<td><br /></td></tr>
<tr><td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">7.</span></td>
<td><b style="font-family: Arial, Helvetica, sans-serif;">if ($x < 4) {</b></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">8.</span></td>
<td><b style="font-family: Arial, Helvetica, sans-serif;"> push (@small_numbers, $x);</b></td></tr>
<tr><td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">9. </span></td>
<td><b style="font-family: Arial, Helvetica, sans-serif;">} elsif ($x < 8) {</b></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">10.</span></td>
<td> <span style="font-family: Arial, Helvetica, sans-serif;"> <b>push (@medium_numbers, $x);</b></span></td></tr>
<tr><td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">11. </span></td>
<td><b style="font-family: Arial, Helvetica, sans-serif;">} elsif ($x < 20) {</b></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">12.</span></td>
<td> <span style="font-family: Arial, Helvetica, sans-serif;"> <b>push (@medium_numbers, $x);</b></span></td></tr>
<tr><td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">13. </span></td>
<td><b style="font-family: Arial, Helvetica, sans-serif;">} else {</b></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">14.</span></td>
<td> <span style="font-family: Arial, Helvetica, sans-serif;"> <b>push (@very_large_numbers, $x);</b></span></td></tr>
<tr><td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">15. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
</div>
<br />
This code is just looking at the number and putting it into an array of small, medium, large or very large numbers. So here I've defined small as below 4, medium between 4 and 7, large between 8 and 19 and very large as 20 and above. I know this makes no sense in the real world but I think it works as an example.<br />
<br />
Again, make sure you spell <b>elsif</b> properly!!!<br />
<b><br /></b>
<br />
<div>
<b>Unless</b><br />
<b><br /></b>
This one is the exact opposite of if and when I see it, it always messes with my head and I have to think about it for a moment - every single time! I think that it's used when it looks cleaner to use rather than having double negatives everywhere or having lots of ands and ors.<br />
<br />
<b>unless</b> (condition) {<br />
code block<br />
}<br />
<br />
Here the code block only runs if the condition is not satisfied:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>unless ($age < 18)</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>{</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> print "Sale approved";</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>}</b></span></td></tr>
</tbody></table>
</blockquote>
This just means that sale approved will only be printed if the customer is 18 or over.<br />
<br /></div>
Anonymoushttp://www.blogger.com/profile/14422352024976746995noreply@blogger.com4tag:blogger.com,1999:blog-5907655605807122632.post-72771495692323220452014-03-11T08:46:00.000-07:002014-03-11T09:43:13.747-07:00HashesHashes are another kind of variable and in my opinion they are pretty similar to arrays. They are indexed, the same as arrays, but instead of being indexed with a number, they are indexed with a user defined string and this index is called a key. This gives us a <b>key/value pair</b>. A good example of this is a dictionary (an actual book dictionary) where the word is the key and the definition is the value.<br />
The value of a hash can be any type of variable - it can be a number, a string, another hash, an array or even a variable name...<br />
<br />
You can tell that you are looking at a hash if it's prefixed by a % sigil. I think it makes more sense to have a hash (#) as the sigil if you're going to call it a hash but never mind, a hash is already reserved for comments.<br />
<blockquote class="tr_bq">
<b>%hash</b></blockquote>
A hash can actually be modelled by using arrays like this:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @french_words = ("bonjour", "au revoir", "merci");</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my $hello = 0;</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my $goodbye = 1;</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my $thank_you = 2;</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">5.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>print $french_words[$goodbye];</b></span></td></tr>
</tbody></table>
</blockquote>
But it looks really strange and clumsy and who wants to bother with all that when a hash works perfectly well?<br />
<br />
<br />
<b>Declaring and assigning</b><br />
<b><br /></b>
Again there are lots and lots and lots of ways of declaring and assigning a hash.<br />
You can declare the hash and then add one element at a time:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my %hash;</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>$hash{"up"} = "down";</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>$hash{"top"} = "bottom";</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>$hash{"charm"} = "strange";</b></span></td></tr>
</tbody></table>
</blockquote>
What does this all mean? - First, I've declared the hash in line 1 using the % sigil and in lines 2 to 4 I've added individual elements to it. The individual elements of the hash are prefixed with a $ because they hold an individual items - a scalar. Then comes the hash name followed by the key you want in curly brackets, the key can be any string. You then assign this to what you want as a value, more on what you can assign to it later.<br />
<br />
or you can declare everything all together:<br />
<blockquote class="tr_bq">
<table><tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my %hash = ("up", "down", "top", "bottom", "charm"</b></span><b style="font-family: Arial, Helvetica, sans-serif;">, "strange"</b><b style="font-family: Arial, Helvetica, sans-serif;">);</b></td>
</tr>
</tbody></table>
</blockquote>
Here I've assigned a list to the hash. The list needs to have an even amount of elements because consecutive elements are paired up into key/value pairs. If you have an odd amount of elements, the last value is going to be undef. In this hash the key/value pairs are up-down, top-bottom and charm-strange.<br />
<br />
This version is more readable:<br />
<blockquote class="tr_bq">
<table><tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>%hash = ("up" => "down", "top" => "bottom", "charm" =></b></span><b style="font-family: Arial, Helvetica, sans-serif;"> "strange"</b><b style="font-family: Arial, Helvetica, sans-serif;">);</b></td>
</tr>
</tbody></table>
</blockquote>
so you can see which are the keys and which are the values more easily.<br />
<br />
Or you can do the even more readable and, I think, preferred by the perl community:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my %hash = (</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> up => "down",</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> top => "bottom",</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> charm => "strange",</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">5.</span></td>
<td><b style="font-family: Arial, Helvetica, sans-serif;">);</b></td>
</tr>
</tbody></table>
</blockquote>
This is exactly the same as the method above it, only spaced out to be clearer.<br />
And of course if I was coding properly all of the "fat commas" (these things "=>") as they're called would all line up, but this blog thing won't let me do that!<br />
<br />
Also the thing about the comma at the end of line 4 applies here as well - you don't need it but it's a good idea to put it there to prevent unnecessary line changes if extra elements are added to the end of the hash. See my array post for more details.<br />
<br />
You may have noticed that in my last code example, I didn't put quotes around the keys. You don't actually need them because the key is always going to be a string and perl knows this. You only need to put quotes if you're including whitespace or other special characters such as "-", so in these cases you need to explicitly stringify (make into a string) the key by using the quotes.<br />
<br />
<br />
<b>Printing</b><br />
As far as I can see, when you print out a hash, they don't necessarily come out in the same order that you declared them in but they do print out in the same order every time you print them. This is because they are printed out in their internal order, which can't be relied on because it will change if you add or delete key/values pairs but will stay the same otherwise. It also changes with the version of perl you're using because the way the keys are ordered has changed several times.<br />
<br />
This is one easy way to print a hash that involves a for loop, which I haven't covered yet. But for the moment, just trust me that it works. This will print out all of the key/value pairs with nice spacing:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">print "$_ $hash{$_}\n" for (keys %hash);</span></b></td></tr>
</tbody></table>
</blockquote>
writing print %hash does the same thing but squashes everything together<br />
<br />
<b>Note </b>The trick I showed to print arrays in my last post doesn't work at all here. If you type print "%hash\n" you will get "%hash" printed to the screen.<br />
<br />
<br />
<b>Accessing and using elements of the hash</b><br />
<br />
<b>Deleting Elements</b><br />
Hashes are not fixed sizes so you can add to them and delete from them as you like. Unlike with arrays, when you delete an element from a hash, there won't be and undefs unless you only get rid of the key or only the value. This means you don't need to worry about having any gaps in your hash.<br />
<br />
To delete a key/value pair, you can do this:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">delete $hash{"up"};</span></b></td></tr>
</tbody></table>
</blockquote>
Note that you only have to specify the key and the value will be automatically found and deleted as well. I guess this would be useful in cases where you might not know the value. Maybe.<br />
<br />
<b>Adding Elements</b><br />
This is exactly the same as when you're first creating the hash and adding one element at a time. If you want to add more elements later on, you just do exactly the same thing:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">$hash{key} = "value";</span></b></td></tr>
</tbody></table>
</blockquote>
There is no need to use "my" because the hash has already been declared, you're just adding to an existing variable.<br />
<br />
<b>What can I put in my hash?</b><br />
You don't always have to have the value as a string, it could be a number or a variable containing a string or a number:<br />
<blockquote class="tr_bq">
<table><tbody>
<tr><td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td><td><b><span style="font-family: Arial, Helvetica, sans-serif;">$hash{key} = $value;</span></b></td></tr>
</tbody></table>
</blockquote>
Or an array or a hash:<br />
<blockquote class="tr_bq">
<table><tbody>
<tr><td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td><td><b><span style="font-family: Arial, Helvetica, sans-serif;">$hash{key} = \@values;</span></b></td></tr>
</tbody></table>
</blockquote>
Be very careful when doing this, you have to make sure that you give it a reference to an array or a reference to a hash rather than the thing itself. I'll go more into these later on but this is how to do it for now. You either put a backslash in front if you're using a variable as above or, if you're putting the hash or array straight in, you need to use [] for arrays and {} for hashes.<br />
<br />
The reason for doing this is because, if you don't, the array or hash will just become part of the original hash you've created, new keys and values will be created. Hopefully this example will explain what I mean:<br />
<br />
<table><tbody>
<tr><td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td><td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my %address = ('Line One' => "5 The Street", 'Town/City' => "London", 'Post Code' => "W15 9QT");</b></span></td></tr>
<tr><td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td><td><br /></td></tr>
<tr><td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td><td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my %person = (</b></span></td></tr>
<tr><td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td><td><b><span style="font-family: Arial, Helvetica, sans-serif;"> Name => "Emma",</span></b> </td></tr>
<tr><td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">5.</span></td><td><b><span style="font-family: Arial, Helvetica, sans-serif;"> Age => 23,</span></b></td></tr>
<tr><td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">6.</span></td><td><b><span style="font-family: Arial, Helvetica, sans-serif;"> Height => "164cm",</span></b></td></tr>
<tr><td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">7.</span></td><td><span style="font-family: Arial, Helvetica, sans-serif;"><b> Address => \%address,</b></span></td></tr>
<tr><td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">8.</span></td><td><span style="font-family: Arial, Helvetica, sans-serif;"><b> );</b></span></td></tr>
</tbody></table>
<br />
The hash drawn out will now look something like this (as you would expect):<br />
<br />
Name => Emma<br />
Age => 23<br />
Height => 164 cm<br />
Address => (<br />
Line One => 5 The Street<br />
Town/City => London<br />
Post Code => W15 9QT<br />
)<br />
<br />
I created a script that would run the code above but I took out the backslash on line 7. Here is what came out:<br />
<br />
Name => Emma<br />
Age => 23<br />
Height => 164cm<br />
Address => Post Code<br />
W15 9QT => Line One<br />
5 The Street => Town/City<br />
London => undef<br />
<br />
This is clearly not what we wanted, instead of a hash within a hash, there is only one big hash.<br />
<br />
And also, if you were reading carefully before, you'll see that I said each element of the hash contains a scalar. Arrays and hashes aren't scalars but their references are so this is another reason why you must make any hashes or arrays into references if you don't want them to be<br />
<br />
Moral of the story, make sure you use a reference if you're going to do a hash within a hash or an array within a hash!!!<br />
<br />
<br />
<b>Editing Elements</b><br />
If you want change a value, you just assign it to the key and the old value will be overwritten:<br />
<blockquote class="tr_bq">
<table><tbody>
<tr><td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td><td><b><span style="font-family: Arial, Helvetica, sans-serif;">$hash{key} = "new value";</span></b></td></tr>
</tbody></table>
</blockquote>
If the key doesn't already exist, a new key/value pair is created so you need to be careful with the spelling of the key when you want to edit a key that's already there or you could end up with the original key and a misspelled version of the key.<br />
<br />
Changing the key of a key/value pair is a lot more tricky. On looking up ways to change it, I think the best way to do it is to delete the key/value pair and start again. You can change it, but it's a lot more code than just deleting and starting again.<br />
<b><br /></b>
<b>Duplication</b><br />
Duplicate keys are not allowed although duplicate values are. If there are duplicate keys declared, only the last one will be acknowledged and the rest will be disregarded. So if we did something like this:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my %hash = (</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> "Name" => "Fred",</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> "Weight" => "70kg",</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> "Height" => "190cm",</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">5.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> "Weight" => "75kg",</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">6.</span></td>
<td><b style="font-family: Arial, Helvetica, sans-serif;">);</b></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">7.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>print $hash{Weight};</b></span></td>
</tr>
</tbody></table>
</blockquote>
The answer printed will be 75kg.<br />
<br />
<b>Can you get the element key from the value?</b><br />
Kind of. With some coding. There's unfortunately no easy trick here. Also values don't have to be unique so you could end up with the wrong key.<br />
<br />
<b>Adding hashes together</b><br />
<b><br /></b>
This is really easy, assuming you already have two hashes that already have things in them (%hash_one and %hash_two), you can just do this:<br />
<blockquote class="tr_bq">
<table><tbody>
<tr><td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td><td><b><span style="font-family: Arial, Helvetica, sans-serif;">%hash_three = (%hash_one, %hash_two);</span></b></td></tr>
</tbody></table>
</blockquote>
Easy!<br />
<br />
<b>Exists - is the key already in the hash?</b><br />
This is useful because duplicate keys aren't really allowed so you can check first if the key already exists before you add a new key/value pair.<br />
<br />
<b>And finally...</b><br />
To get a list of all the keys in the hash:<br />
<blockquote class="tr_bq">
<b><span style="font-family: Arial, Helvetica, sans-serif;">print keys(%hash);</span></b></blockquote>
And to get a list of all the values in the hash - you guessed it:<br />
<blockquote class="tr_bq">
<b><span style="font-family: Arial, Helvetica, sans-serif;">print values(%hash);</span></b></blockquote>
<br />Anonymoushttp://www.blogger.com/profile/14422352024976746995noreply@blogger.com0tag:blogger.com,1999:blog-5907655605807122632.post-62432479652891095662014-02-19T01:00:00.000-08:002014-02-20T01:06:27.200-08:00How does sort actually work?I talked about <b>sort</b> in my last post, but I started to read more about it and got wondering, how does it actually work?<br />
<br />
You can use sort to order lists numerically or lexically. To sort lexically you use the cmp operator within the curly braces:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">sort{$a cmp $b}("please", "sort", "this", "list");</span></b></td></tr>
</tbody></table>
</blockquote>
and for sorting numerically, you use the <=> operator:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">sort{$a <=> $b}(13,2,8,1,3,1,5,21);</span></b></td></tr>
</tbody></table>
</blockquote>
What I think this means is that $a and $b refer to the two strings or numbers that are being compared when the algorithm is run. The letter "a" comes before the letter "b" in the alphabet and $a is put in front of $b in the code which means that words beginning with a letter that comes before other words in the alphabet should be sorted in front of those other words. Hopefully this all makes sense and is actually accurate.<br />
<br />
Perl 5.6 and earlier used the quicksort algorithm and perl 5.7 and onwards, uses the merge sort algorithm. On wikipedia (<a href="http://en.wikipedia.org/wiki/Merge_sort">http://en.wikipedia.org/wiki/Merge_sort</a>) there's a pretty good animation at the top of the page that shows how merge sort works.<br />
<br />
<b>Quicksort - perl 5.6 and earlier</b><br />
<b><br /></b>
I remember learning this at school and uni and thinking it's pretty cool but also wondering what it was used for. We had to write a program in Java that carried out a quicksort. I should have just submitted one line of perl code...<br />
<br />
Quicksort is a divide and conquer algorithm and there are different variations of it based on which position you choose for the pivot (explanation very soon) but I couldn't find out which version was used for sort in perl. So for simplicity, and because it's how I was taught, I'm going to choose the pivot and the value in the middle of the list.<br />
<br />
So we have a list of numbers (assuming we're using numbers and sorting them in ascending numerical order) and the value in the centre of the list is the pivot. All numbers lower than the pivot are put on the left of this pivot and all numbers higher are put on the right. This creates three different lists - numbers lower than the pivot, numbers higher than the pivot and the pivot itself. The pivot list is one element long and is considered sorted so now we need to sort the other two lists in the same way. For each list, a pivot is chosen and again, lower numbers go on the left and higher numbers go on the right. This now creates seven lists. This continues until you have lists containing only one element, putting these lists all together will give one sorted list. Here's an example (please feel free to skip the example if you already know how it works or if it doesn't interest you!):<br />
<br />
(4,2,9,6,<span style="background-color: yellow;">5</span>,1,8,7,3)<br />
<br />
The number in the centre of the list is the pivot.<br />
<br />
Starting from the left, numbers lower than 5 are put into one list to the left and numbers higher than 5 are put into another list on the right. 4 is taken out first giving:<br />
<br />
(4) (2,9,6,<span style="background-color: yellow;">5</span>,1,8,7,3)<br />
<br />
Then 2 is taken out and put in the list on the left:<br />
<br />
(4,2) (9,6,<span style="background-color: yellow;">5</span>,1,8,7,3)<br />
<br />
Then 9:<br />
<br />
(4,2) (6,<span style="background-color: yellow;">5</span>,1,8,7,3) (9)<br />
<br />
This is repeated, excluding the pivot until we have three list with the pivot on its own:<br />
<br />
(4,2,1,3) (5) (9,6,8,7)<br />
<br />
Pivots are now chosen from any lists with more than one element. I think this time, as there is no real middle element, I will use the (n+1)/2th element.<br />
<br />
(4,2,<span style="background-color: yellow;">1</span>,3) (5) (9,6,<span style="background-color: yellow;">8</span>,7)<br />
<br />
The same is applied starting with the first list - all element lower than one go on the left and all numbers higher than one go on the right:<br />
<br />
(1) (4,2,3) (5) (9,6,<span style="background-color: yellow;">8</span>,7)<br />
<br />
The same is applied to the other list:<br />
<br />
(1) (4,2,3) (5) (6,7) (8) (9)<br />
<br />
Again, pivots are picked for the lists with more than one element:<br />
<br />
(1) (4,<span style="background-color: yellow;">2</span>,3) (5) (6,<span style="background-color: yellow;">7</span>) (8) (9)<br />
<br />
And the same sorting is applied giving:<br />
<br />
(1) (2) (3,<span style="background-color: yellow;">4</span>) (5) (6) (7) (8) (9)<br />
<br />
Then the final list that contains more than one element is sorted:<br />
<br />
(1) (2) (3) (4) (5) (6) (7) (8) (9)<br />
<br />
Put this all together and you have a sorted list:<br />
<br />
<span style="background-color: yellow;">(1,2,3,4,5,6,7,8,9)</span><br />
<br />
<b>Merge Sort - perl 5.7 onwards</b><br />
<br />
So all of that wasn't entirely relevant for those of you that have upgraded your perl version since 2002 because from perl 5.6, the sort function has used the merge sort algorithm.<br />
<br />
Merge sort is also a divide and conquer algorithm. It works by splitting up the list into individual elements. Each element is compared to its neighbour and (again assuming we're using numbers and sorting them in ascending numerical order) the smaller number is put on the left and the larger on the right. Then the next set of pairs are compared and so on until the end of the list. Then these sorted pair are compared to each other and ordered to make groups of four. Then these sorted groups are compared to the other groups and this is repeated until the whole list is in one big, sorted group. Hopefully this example will make all this clearer (again, feel free to skip this bit if you don't really care!):<br />
<br />
Say we have a list of:<br />
<br />
(4,2,6,5,1,8,7,3)<br />
<br />
We then split it into sublists which contain one individual element. This means we have eight sublists of single elements:<br />
<br />
(4) (2) (6) (5) (1) (8) (7) (3)<br />
<br />
Then we compare the elements to their next door neighbour. First will be (4) and (2). 2 is smaller so goes in front of 4 and we have our first sorted pair of (2,4)<br />
<br />
(2,4) (6) (5) (1) (8) (7) (3)<br />
<br />
The smallest sublists are always compared first so we compare the next two single element sublists - (6) and (5) giving:<br />
<br />
(2,4) (5,6) (1) (8) (7) (3)<br />
<br />
This is continued until all the sublists contain two sorted elements:<br />
<br />
(2,4) (5,6), (1,8) (7) (3)<br />
<br />
(2,4) (5,6) (1,8) (3,7)<br />
<br />
Then the pairs are compared to each other starting with (2,4) and (5,6) and always comparing the first element of each list. First 2 and 5 are compared, 2 is smaller so is taken out to make a new list:<br />
<br />
(<span style="background-color: yellow;">2</span>,4) (<span style="background-color: yellow;">5</span>,6) (1,8) (3,7)<br />
<br />
(2 <br />
<br />
Then the first elements of the target sublists are compared so 4 and 5, 4 is smaller so is taken out making:<br />
<br />
(<span style="background-color: yellow;">4</span>) (<span style="background-color: yellow;">5</span>,6) (1,8) (3,7)<br />
<br />
(2,4 <br />
<br />
Then there's only one target sublist left so elements are taken out one by one from the front:<br />
<br />
(<span style="background-color: yellow;">5</span>,6) (1,8) (3,7)<br />
<br />
(2,4,5 <br />
<br />
(<span style="background-color: yellow;">6</span>) (1,8) (3,7)<br />
<br />
(2,4,5,6)<br />
<br />
And finally:<br />
<br />
(2,4,5,6) (1,8) (3,7)<br />
<br />
Then the pairs (1,8) and (7,3) are compared in the same way with intermediate steps:<br />
<br />
(2,4,5,6) (<span style="background-color: yellow;">1</span>,8) (<span style="background-color: yellow;">3</span><span style="background-color: white;">,7</span>)<br />
<br />
(1<br />
<br />
(2,4,5,6) (<span style="background-color: yellow;">8</span>) (<span style="background-color: yellow;">3</span><span style="background-color: white;">,7</span>)<br />
<br />
(1,3<br />
<br />
(2,4,5,6) (<span style="background-color: yellow;">8</span>) (<span style="background-color: yellow;">7</span>)<br />
<br />
(1,3,7<br />
<br />
(2,4,5,6) (<span style="background-color: yellow;">8</span>)<br />
<br />
(1,3,7,8)<br />
<br />
Giving us two sorted lists of:<br />
<br />
(2,4,5,6) (1,3,7,8)<br />
<br />
Finally these two sublists are compared in the same way to give one sorted list of<br />
<br />
<span style="background-color: yellow;">(1,2,3,4,5,6,7,8)</span><br />
<br />
If that doesn't make sense, again, I highly recommend looking at the animation on the wikipedia page.<br />
<br />
<br />
<b>Why was quicksort ditched in favour of merge sort?</b><br />
<br />
According to the perl docs, the quicksort algorithm used was <b>unstable</b> because it can become <b>quadratic</b>. What????<br />
<br />
A <b>stable</b> sort preserves the order of list elements that compare equal so maybe the quicksort algorithm kept sorting list items that were exactly the same as each other, which made the run time and complexity higher.<br />
<br />
The run time of both of these algorithms comes out as O(n log n) when averaged over all arrays of length n. However, because quicksort does not always preserve the order of equal elements, its run time can become O(n^2) - which is a <b>quadratic</b> because the n is squared. This behaviour doesn't happen with merge sort so quicksort was replaced.<br />
<br />
The perl docs do say that for "some inputs" on "some platforms" the original quicksort was faster, but no other information is given - I'm not sure which inputs or which platforms, but I'm sure that these are a minority. Also as an extra note, I think that 99.99% of the time, any time or performance differences will not be large enough to be noticeable anyway.<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/14422352024976746995noreply@blogger.com7tag:blogger.com,1999:blog-5907655605807122632.post-52529536475773244732014-02-13T06:22:00.001-08:002014-05-13T07:37:07.263-07:00Lists, Lists, Lists<b>List or Array?</b><br />
<b><br /></b>
I've written a post about arrays and kind of glossed over the array/list distinction. Some people got back to me about the fact that I hadn't really talked about lists at all so here I'm going to try to explore what a list is and how it differs from an array.<br />
<br />
A list is just what it sounds like - a number of items separated by a comma.<br />
An array is assigned a list, it contains the list but it isn't the list itself. I don't think that you can access elements in a list via index numbers unless you explicitly do something to make it be treated like an array.<br />
<br />
So this is a list:<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;"><b>("apples", "bananas", "cherries", 45, 360)</b></span></blockquote>
<br />
We can assign it to an array:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @array = </b></span><b><span style="font-family: Arial, Helvetica, sans-serif;">("apples", "bananas", "cherries", 45, 360);</span></b></td></tr>
</tbody></table>
</blockquote>
And this is an array:<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;"><b>@array</b></span></blockquote>
<br />
In my post about arrays, I showed a way to get the number of elements in an array using scalar(@arr) and I also talked about using scalar on a list but I didn't explain it very well.<br />
<br />
So if we have:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">my @arr = ("this", "is", "a", "list);</span></b></td></tr>
</tbody></table>
</blockquote>
The difference between<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">print scalar(@arr);</span></b></td></tr>
</tbody></table>
</blockquote>
and<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">print scalar("this", "is", "a", "list");</span></b></td></tr>
</tbody></table>
</blockquote>
<br />
is that the first one is giving the scalar value of an array, which is the number of elements in the array (4) and the second one is giving the scalar value of a list, which is the value of the last element ("list"). Two very similar statements, but giving you very different results - I think this is very strange behaviour.<br />
<br />
<br />
<b>Note</b>
To prevent you from having to type loads of quotes in your list, which I know for me definitely slows down my typing and results in a lot of pressing the wrong keys, you can do this:<br />
<br />
my @arr = ("this", "is", "a", "list");<br />
<br />
my @arr = qw(this is a list);<br />
<br />
Much quicker and qw stands for "quote word". The only problem is that the space between the words means that the words are separate list items so if you want to include a space in one of your list items, you're going to have to use quotes.<br />
<br />
You can do lots of things with lists and here are some of them.<br />
<br />
The following only work on an array so you have to assign your list to an array first.<br />
<br />
<b><u>Pop</u></b><br />
<b><u><br /></u></b>
This takes the last element from the array and gives it to what you are assigning it to.<br />
<br />
my @arr = (1,2,3,4,5);<br />
my $val = pop(@arr);<br />
<br />
$val has the value 5 and @arr is now (1,2,3,4)<br />
<br />
<b><u>Push</u></b><br />
<b><u><br /></u></b>
This one is kind of the opposite of pop. Instead of taking away from the end of the array, you add an element on to the end of it.<br />
<br />
my @arr = (1,2,3,4,5);<br />
push (@arr, "x");<br />
<br />
@arr is now (1,2,3,4,5,"x")<br />
<br />
<b><u>Shift</u></b><br />
<b><u><br /></u></b>
This is a different opposite of pop. Instead of taking the last element of the list and assigning it to a value, you take the first element.<br />
<br />
my @arr = (1,2,3,4,5);<br />
my $val = shift(@arr);<br />
<br />
$val has the value 1 and @arr is now (2,3,4,5)<br />
<br />
<b><u>Unshift</u></b><br />
<b><u><br /></u></b>
This is the opposite of shift and push. An element is added to the front of the array.<br />
<br />
my @arr = (1,2,3,4,5);<br />
unshift (@arr, "x");<br />
<br />
@arr is now ("x",1,2,3,4,5)<br />
<br />
<br />
I think this little table sums up everything above:<br />
<br />
<table border="1" cellpadding="5">
<tbody>
<tr>
<td></td>
<td><b>Beginning or end of array</b></td>
<td><b>Add or remove element</b></td>
</tr>
<tr>
<td><b>Pop</b></td>
<td>End</td>
<td>Remove</td>
</tr>
<tr>
<td><b>Push</b></td>
<td>End</td>
<td>Add</td>
</tr>
<tr>
<td><b>Shift</b></td>
<td>Beginning</td>
<td>Remove</td>
</tr>
<tr>
<td><b>Unshift</b></td>
<td>Beginning</td>
<td>Add</td></tr>
</tbody></table>
<br />
<b><br /></b>
<b>Sort</b><br />
<b><br /></b>
You can also sort your lists using the sort function:<br />
<br />
<b>Lexically:</b>
<br />
<br />
If sort is used by itself with no parameters, it will sort the list in standard string comparison order, which basically means alphabetical order. You can either use sort directly on a list as I have below or you can assign the list to an array and use sort on the array. Just type "sort" before the list or before the array.<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">my @arr = sort</span></b><b><span style="font-family: Arial, Helvetica, sans-serif;">("hello", "my", "name", "is", "emma")</span></b><b><span style="font-family: Arial, Helvetica, sans-serif;">;</span></b></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">print "@arr\n";</span></b></td></tr>
</tbody></table>
</blockquote>
When this the above code is run, it will come out with:<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">emma hello is my name</span></blockquote>
This can also be written as<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;"><b>sort {$a cmp $b} ("hello", "my", "name", "is" "emma");</b></span> </blockquote>
<b>Note</b><br />
If you have words beginning with capital letters, these will always be sorted in front of lower cased words, even if they come after the lower cased word alphabetically.<br />
<br />
To sort the words into a backwards order just reverse the a and b:<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;"><b>sort {$b cmp $a} ("hello", "my", "name", "is" "emma");</b></span></blockquote>
<br />
<b>Numerically:</b><br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">my @arr = sort{$a<=>$b}(7,9,4,2,8);</span></b></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">print "@arr\n";</span></b></td></tr>
</tbody></table>
</blockquote>
To sort numerically, you use the <=> operator rather than cmp and you still use $a and $b to represent the two numbers being sorted in the alogorithm. When the above code is run, you will get:<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;"><b>(2,4,7,8,9)</b></span></blockquote>
<div>
Again, to sort backwards, you reverse the a and b:</div>
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">my @arr = sort{$b<=>$a}(7,9,4,2,8);</span></b></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">print "@arr\n";</span></b></td></tr>
</tbody></table>
</blockquote>
This will print:<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;"><b>(9,8,7,4,2)</b></span> </blockquote>
<b>List mapping</b><br />
<b><br /></b>The map function is used to transform lists element-wise. You can go through each element of a list and perform a function on it and a new list of the new values will be created.<br />
<br />
To do the map function, you say that you want to put the result into a new array (@new_numbers in the code below), then you type an equals sing, then the word "map" and then what you want to do to each element in curly brackets. $_ refers to each individual element, kind of like x in a mathematical equation. In the code below what I've said is to take each element and times that element by two. Then you type the list that you want to perform the operation on - you can either write the list out or give an array like I've done.<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">my @numbers = (1,2,3,4,5);</span></b></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">my @new_numbers = map{$_*2}@numbers;</span></b></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">print "@new_numbers\n";</span></b></td></tr>
</tbody></table>
</blockquote>
Which will print:<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;"><b>2 4 6 8 10</b></span></blockquote>
You can also apply map to text:<br />
<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @text = </b></span><b><span style="font-family: Arial, Helvetica, sans-serif;">("this", "is", "a", "list");</span></b></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">my @new_text = map{$_.":"}@text;</span></b></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">print "@new_text\n";</span></b></td></tr>
</tbody></table>
</blockquote>
Which will print:<br />
<blockquote class="tr_bq">
<b><span style="font-family: Arial, Helvetica, sans-serif;">this: is: a: list:</span></b></blockquote>
<br />
<b>Grep</b><br />
<b><br /></b>Grep is similar to sort, although instead of applying a change to each element, it evaluates the result of the operation and if the result is true, the original value will be put into a new list, if the result is false, the original value will be filtered out.<br />
<br />
Again you start with the array you want your new list to be put into (@multiples_of_two), then an equals sign and then the evaluation you want is put in curly braces. The evaluation must create an answer that is either true or false. Then you give the list, either written out as a list or as an array. The code below goes through the list of 1-10 and puts the multiples of two into a new list.<br />
<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @numbers = </b></span><b><span style="font-family: Arial, Helvetica, sans-serif;">(1,2,3,4,5,6,7,8,9,10);</span></b></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">my @multiples_of_two = grep{$_%2==0}@numbers;</span></b></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3. </span></td>
<td><b><span style="font-family: Arial, Helvetica, sans-serif;">print "@multiples_of_two\n";</span></b></td></tr>
</tbody></table>
</blockquote>
This will print:<br />
<blockquote class="tr_bq">
<b><span style="font-family: Arial, Helvetica, sans-serif;">(2,4,6,8,10)</span></b></blockquote>
Anonymoushttp://www.blogger.com/profile/14422352024976746995noreply@blogger.com10tag:blogger.com,1999:blog-5907655605807122632.post-46312307530763655542014-02-06T09:05:00.001-08:002014-02-07T01:02:24.756-08:00@arr = ("my", "first", "array");Now, I know that arrays are a huge topic so I can't possibly fit everything into one post or you'll all get really bored. So here are some of what I think are the key points to understanding arrays, enjoy...<br />
<br />
Arrays are just data structures where we can store a list of singular things (scalars) in a specific order. They are like lists, but each element is associated with an incremental number and you can access each of these elements using its associated number. In fact you can assign a list to an array variable name and it will turn into an array.<br />
<br />
Arrays are really important, in my clearly expert opinion, because sometimes we need to store things in a specific order and sometimes it makes sense to store a lot of scalars together in one place. You can also do a lot of things with them like iterate through each entry or do the same thing to each entry and put it into a new array. That kind of thing. You can store numbers and strings and arrays and other scalars and mixtures of all of those things into the elements of the array. Here's how:<br />
<br />
You can tell you are looking at an array if the variable name is prefixed by an @ sign so for example:<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">@myarray</span></blockquote>
I've recently found out that punctuation marks in front of variables in perl are actually called <b>sigils</b> so I may or may not start calling them that from now on.<br />
<br />
<br />
<b>Declaring and Assigning</b><br />
<br />
As with many things (nearly everything) in perl, arrays can be declared and assigned in different ways:<br />
<br />
These two ways show the whole array being created in one go - a list is created and then this list is assigned to the array name:<br />
<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @arr;</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>@arr = ("this", "is", "array", 1);</b></span></td>
</tr>
</tbody></table>
</blockquote>
<br />
Note that strings are in quotes and numbers are not<br />
<br />
or<br />
<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @arr = ("this", "is", "array", 2);</b></span></td>
</tr>
</tbody></table>
</blockquote>
Arrays can also be created one element at a time:<br />
<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @arr;</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>$arr[0] = "this";</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>$arr[1] = "is";</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>$arr[2] = "array";</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">5.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>$arr[3] = 3;</b></span></td>
</tr>
</tbody></table>
</blockquote>
<br />
Note that the array index starts at 0 and also that when you assign something to the individual array positions, you use a $ sign (sigil!). This is because each array entry is a singular piece of data, and from my post about scalars, we know that singular pieces of data are stored in scalars and scalars are identified by a $ sign.<br />
<br />
If you skip out element positions when you are creating an array like this:<br />
<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @arr;</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>$arr[0] = "this array";</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>$arr[2] = "has";</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>$arr[5] = "some";</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">5.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>$arr[6] = "gaps";</b></span></td></tr>
</tbody></table>
</blockquote>
<br />
When you print it out, you will get:<br />
<br />
this array, undef, has, undef, undef, some, gaps<br />
<br />
<br />
<b>Accessing the elements</b><br />
<b><br /></b>
Once you've declared and assigned your array, you probably want to do things with it. You can access each element by referring to it's index number, remembering that it starts from 0. So for the array<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @myarray = ("this", "array", "is", 6, "elements", "long");</b></span></td></tr>
</tbody></table>
</blockquote>
<br />
To print the word "is", you need to use the $ sigil as it's a single piece of data, then the name of the array, then a 2 in square brackets because "is" is in the array with element index 2:<br />
<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>print $myarray[2];</b></span></td></tr>
</tbody></table>
</blockquote>
<br />
<table border="1" cellpadding="5">
<tbody>
<tr>
<td><b>Tip</b><br />
<br />
If you want to print out your whole array with a space in between each element, you need to write something like:<br />
<br />
print "@array\n";<br />
<br />
This interpolates all of the array elements into a string and by default, each element is separated by a space.</td>
</tr>
</tbody></table>
<br />
<b>Length of Arrays</b><br />
<b><br /></b>
You can either use<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">scalar(@arr)</span></blockquote>
<br />
or<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">$#arr+1</span></blockquote>
<br />
The first one makes more sense and I think it's easier to understand. It just gives you the array as a scalar value which turns out to be the number of elements it contains. The second one gives you the index value of the last element in the array and because the index starts from 0, you have to <complete id="goog_967561473">+</complete>1 to get the number of elements.<br />
<br />
There's something you need to be careful about within this topic and I think it's a bit of a red herring. If you write:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>print scalar(100, 300, 200);</b></span></td></tr>
</tbody></table>
</blockquote>
The answer you will get is:<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">200</span></blockquote>
this is because it's giving us the value of the last item in the array. So watch out!<br />
<br />
<b>Iterating through arrays </b>- this topic is a bit more complex and needs scary things like loops, which I'll cover later so I'm going to run away from it now...<br />
<br />
<br />
<b>Array of arrays</b><br />
<br />
I think my brain is exploding at trying to visualise this. You can put as many arrays in arrays in arrays in arrays as you like and end up with a multi-dimensional mess. But as long as you can understand it and everyone reading your code can understand it, then everything is fine.<br />
<br />
There are, again, many ways implement this. You can declare some arrays and then put all of these into one big array:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @name1 = ("Emma", "Jane", "Howson", 23);</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @name2 = ("Willard", "Carroll", "Smith", 45);</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @name3 = ("Tyra", "Lynne", "Banks", 40);</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my@name4 = ("Alecia", "Beth", "Moore", 34);</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">5.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my@name5 = ("David", "Boreanaz", 44);</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">6.</span></td>
<td><br /></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">7.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my@perfectdinnerparty = (\@name1, \@name2, \@name3, \@name4, \@name5);</b></span></td></tr>
</tbody></table>
</blockquote>
On line 7 you may have notice the backslashes before the @ sigils. This is to prevent one giant array being created where 23 is the 4th element in the array with an index of 3, "Willard" will then become the 5th element in the array with an index of 4 and "Carroll" will be the 6th element with an index of 5 etc. The backslashes actually turn the arrays into array refs, which I don't understand at the moment but I'll get to in a later post. All I know is they enable the structure of an array of arrays.<br />
<br />
Or you can declare them all at once:<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>my @perfectdinnerparty = (</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> ["Emma", "Jane", "Howson", 23],</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> ["Willard", "Carroll", "Smith", 45],</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> ["Tyra", "Lynne", "Banks", 40],</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">5.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> ["Alecia", "Beth", "Moore", 34],</b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">6.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b> ["David", "Boreanaz", 44]<span style="background-color: yellow;">,</span></b></span></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">7.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>);</b></span></td></tr>
</tbody></table>
</blockquote>
<br />
The outer brackets need to be parentheses () and the inner ones surrounding each array element need to be square brackets [] and these indicate that the contents are also an array ref.<br />
<br />
Another note is that you need to put commas between each outer array element (so between each set of square brackets), but you don't need to put a comma after the last array entry (where it's highlighted). I think it's good practise to do this anyway because if you need to add another element (another square bracket set) to the array, you only need to alter one like of code.<br />
<br />
<b>Accessing elements in an array of arrays</b><br />
<b><br /></b>
The process is very similar to an array although there are two numbers in brackets to find the location of the element you need. So to get the string "Smith" from my perfectdinnerparty array, I would use:<br />
<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>$perfectdinnerparty[1][2];</b></span></td></tr>
</tbody></table>
</blockquote>
<br />
The first number is the index of the number of arrays in the super array and the second number is the index of the element in each array in square brackets.<br />
<br />
<b>Another note</b><br />
<br />
$var and @var are two completely different variables and have nothing to do with each other. You can't access one by using the other one so it's probably best not to use the same variable name to avoid confusion. Another case of just because you can do it, doesn't mean you should.<br />
<br />
<br />
As always, please correct me if I'm wrong with anything and any suggestions of how to find out more are welcome.Anonymoushttp://www.blogger.com/profile/14422352024976746995noreply@blogger.com10tag:blogger.com,1999:blog-5907655605807122632.post-48829302862717274342014-01-28T09:51:00.002-08:002014-01-30T01:30:55.184-08:00"Strings"<b><span style="font-size: large;">Strings</span></b><br />
<b><br /></b>A string is basically any amount of characters in sequence including zero characters, which is known as the empty string. Similarly to numbers, the maximum size or length of a string is basically limited to your computer's memory, which is probably far larger than any real string you're going to work with.<br />
<br />
These are all examples of strings:<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">"Hello"<br />""<br />"This is a string"<br />"This 1 is a 2 string 3 including 4 some 5 numbers 8907"<br />"27195"<br />"<span style="background-color: #fffff2; font-size: 24px; white-space: nowrap;">☆</span><span style="background-color: #fffff2; font-size: 24px; white-space: nowrap;">☘</span><span style="background-color: #fffff2; font-size: 24px; white-space: nowrap;">☺</span>"<br />"مرحبا"</span></blockquote>
<br />
Perl has full support for unicode (basically any letter or symbol or number in any language you can think of), but if you're going to use characters out of the ASCII range in your program (so variable names and other bits of code that aren't in single quoted strings), you'll need to use the pragma<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">use utf8;</span></blockquote>
<br />
I think it doesn't use unicode by default for historical reasons so when Perl was written, there was only a need to use ASCII characters.<br />
<br />
<br />
<b><span style="font-size: large;">Quotes</span></b><br />
<br />
Strings are surrounded by either single or double quotes or delimiters that imply quotes - more on these later. These quotes and delimiters are not part of the string itself, they just indicate that whatever is inside should be treated as a string.<br />
<br />
<br />
What is the difference between having single and double quotes?<br />
<b><br />
Single quotes</b> mean that whatever is in the quotes is represented literally so newline characters or any other control characters are not interpreted as control characters, they are just printed out literally:<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">print 'Hello everyone\n'</span></blockquote>
<br />
will print:<br />
Hello everyone\n<br />
which is probably not what you want to see in most cases.<br />
<br />
The only character that is interpreted is the backslash. This is to enable you to use a single quote in a string. For example:<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">'I\'m a Perl programmer'</span></blockquote>
<br />
The backslash means that the quote doesn't end where the single quote is used as an apostrophe (if that makes sense). You can use a single backslash in your string if it isn't at the end of the string. If you do want a backslash at the end of a string, you need to put two in a row. I would say it is advisable to always use two backslashes in a row incase this kind of thing happens as two backslashes will always print just one.<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">'This string contains one backslash \\'</span></blockquote>
<span style="font-family: inherit;">This will print:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">This string contains one backslash \</span><br />
<br />
<b>Double quotes</b> interpret special symbols so you can include all sorts of control characters as well as displaying characters through octal and hex representations. You can also embed other variables into the string.<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">my $name = "Emma\n"; # will print 'Emma' and then a newline</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">my $string = "Hello $name"; # will print 'Hello Emma'</span></blockquote>
<br />
<b>Delimiters</b> are useful if you want to use quotes inside your string are used by first typing 'q' for a single quoted string and 'qq' for a double quoted string. Then you type the character that you want to be the delimiter, then write out the string with no quotes and then add the delimiter character at the end.<br />
<br />
I thought a delimiter could be any character, but I tried to use letters and numbers and they don't seem to work and anyway using these wouldn't be very advisable because it doesn't look very clear. It does work with any type of punctuation and it's usually useful to have it as a character that doesn't appear in your string because otherwise you have to use a backslash to escape your delimiter character and all this can start to look a bit confusing.<br />
For example:<br />
<br />
<blockquote class="tr_bq">
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">'Hello World!'</span><br />
<span style="font-family: inherit;">is equal to all of these: </span></blockquote>
</blockquote>
<blockquote class="tr_bq">
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">q(Hello World!)</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">q{Hello World!}</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">q.Hello World!.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></blockquote>
</blockquote>
<blockquote class="tr_bq">
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">"Hello World!"</span><br />
<span style="font-family: inherit;">is equal to all of these: </span></blockquote>
</blockquote>
<blockquote class="tr_bq">
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">qq/Hello World!/</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">qq[Hello World!]</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">qq?Hello World!?</span></blockquote>
</blockquote>
I told a lie - you don't always use exactly the same character as you did to start the string. If you notice the brackets always start with a left bracket and end with a right one. Interestingly, you can use two close brackets but you can't use two open brackets. Maybe because if you open a bracket it expects a close bracket and gets very confused and upset if you don't give it one.<br />
<br />
You can use punctuation marks like $, @ and % as delimiters. Also very inadvisable because these are used commonly to declare scalars, hashes and arrays and you don't want to confuse yourself or other poor people that have to look at your code.<br />
<br />
<b><span style="font-size: large;">String Manipulations</span></b><br />
<br />
There are many many many things you can do with a string in Perl, far too many to list in this post. Some of the main ones and ones that I think would be useful are as follows:<br />
<br />
<b>Concatenation</b><br />
<br />
To concatenate (join together) two or more strings you use the . operator.<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">my $string1 = "apple";<br />my $string2 = "pear";<br />my $string3 = "peach";<br />my $all = $string1.$string2.$string3;<br />print $all; </span></blockquote>
This will print:<br />
<span style="font-family: Arial, Helvetica, sans-serif;">applepearpeach</span><br />
<br />
You don't have to just concatenate variable names, you can also add in new strings:<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">print $string1.", ".$string2." and ".string3;</span></blockquote>
<br />
will print:<br />
<span style="font-family: Arial, Helvetica, sans-serif;">apple, pear and peach</span><br />
<br />
<b>Repetition</b><br />
<br />
To repeat a string, you put the string in quotes, then x, then the number of times to repeat the string.<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">print 'Hello' x 5;</span></blockquote>
<br />
This will print:<br />
<span style="font-family: Arial, Helvetica, sans-serif;">HelloHelloHelloHelloHello</span><br />
<br />
<b>Interpolation</b><br />
<b><br /></b>
Interpolation means that you can include a variable in a string and if you put that string in double quotes, the value of the variable will be printed. You <u>must</u> use double quotes for interpolation, because if you use single quotes, the string will be printed literally and you will just see the variable name.<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">my $name = "Emma";<br />print "The variable \$name has the value $name";</span></blockquote>
<br />
This will print:<br />
<span style="font-family: Arial, Helvetica, sans-serif;">The variable $name has the value Emma</span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
And that's the end of my very long post, congratulations if you've made it this far!Anonymoushttp://www.blogger.com/profile/14422352024976746995noreply@blogger.com5tag:blogger.com,1999:blog-5907655605807122632.post-74736213868457030122014-01-22T08:15:00.005-08:002014-01-23T09:26:26.446-08:00NumbersMany different types of numbers can be represented in Perl. The good thing is that you don't have to specify what kind of number you are using as the interpreter can work it out for itself.<br />
<br />
<br />
<b>Integers</b><br />
<b><br /></b>
Integers consist of any whole number either with a sign or without:<br />
<b><br /></b>
1<br />
0<br />
2014<br />
-365<br />
7875493754977009<br />
<br />
Perl allows you to add underscores to integers to make them easier for a human to read so for the last number in the list you can write:<br />
<br />
7_875_493_754_977_009<br />
<br />
This makes absolutely no difference to what the number is or how it is handled, it's just easier for our inferior mortal brains to comprehend.<br />
<br />
There aren't really limits as to the highest and lowest integers that can be stored. The limits are basically subject to your computer's memory but I don't think in practise anyone really wants to use numbers that large. Also you will be sacrificing some precision when your numbers get that large and I think the reason for this is similar to why floating points are not entirely precise. Although I could be making that up.<br />
<br />
So, on to floating points...<br />
<br />
<br />
<b>Floating Points</b><br />
<b><br /></b>
Floating points are numbers with a decimal point and also with or without a sign.<br />
As with most programming languages, integers are (mostly) represented exactly but floating points are an approximation of what the decimal places are. It seems to me that this is because numbers are stored in binary and some fractions, for example a third, can only be expressed with an infinite binary representation. Seeing as computers do not have infinite memory, we have to chop off the end of the number and store the closest thing we have.<br />
I think this level of precision is sufficient for most applications but I guess for research or anything scientific that requires precision, something else is going to be needed.<br />
<b><br /></b>1.5<br />
-23.45<br />
550.0<br />
-1.0<br />
5.43e24<br />
-5.2e28<br />
-5e-12<br />
6.34e-13<br />
<br />
The 'e' in the middle of some of the numbers above mean that they are using the exponent. So 5.43e24 means 54.3 X 10^23 or 543 followed by 22 zeroes.<br />
<br />
<br />
<b>Non-decimal Integers</b><br />
<b><br /></b>I always forget about these types of numbers, it makes me stop and remember that the only reason we count the way we do is because we have ten fingers and in a parallel world, eight-fingered martians are learning about this weird decimal way of counting.<br />
<br />
I'm not really sure why anyone would use these in a real world application - maybe I'll see later on.<br />
<br />
With non-decimal numbers, we have to indicate which type of numerical system we are using, otherwise they will just be treated as decimal numbers. The way to indicate these are really simple and not at all cumbersome:<br />
<br />
<b>Binary</b><br />
0b1101110 - all binary numbers start with '0b'<br />
<b>Octal</b><br />
0156 - all octal numbers start with a '0'<br />
<b>Hexadecimal</b><br />
0x6e - all hex numbers start with '0x'<br />
<br />
all the above amount to 110<br />
<br />
These numbers can also be signed or unsigned.<br />
<b><br /></b>
<b>Numeric Operators</b><br />
<br />
Perl allows you to use operators on numbers so you can do calculations, these are the main ones:<br />
<br />
<b>+</b> addition<br />
<b>-</b> subtraction<br />
<b>*</b> multiplication<br />
<b>/</b> division - this will always give you the floating point value if the result of the division is not an integer<br />
<b>%</b> modulus - the values are always reduced to integers first, for example 10.5 % 3.2 will be calculated using 10 % 3 where the answer will be 1<br />
<b>**</b> exponentiation - for example 2**3 means 2^3 or two to the power of three where the answer will be 8<br />
<br />
So now we can do things like:<br />
<br />
my $sum = 24 + 12;<br />
my $subtraction = 10.5 - 5.3;<br />
my $exponentiation = $sum**$subtraction;<br />
<br />
As always, please add comments to this or any other of my posts. I'm a beginner so I need feedback on anything I've written that's wrong and also any extra information or helpful links or anything else you can think of that will help me learn is appreciated.<br />
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/14422352024976746995noreply@blogger.com3tag:blogger.com,1999:blog-5907655605807122632.post-77652798551915385212014-01-21T09:05:00.001-08:002014-01-21T09:05:34.362-08:00my $scalar;In most of the books I'm using, the first thing after all the set up and hello world stuff is scalars. This seems to be sensible to me because they're quite simple for a beginner to understand and seemingly fundamental to the Perl language.<br />
<br />
From what I understand, scalars make up any singular piece of data - it's when Perl has one of something and often this will be a number or a string but not an array or hash or other complex data type. You can identify a scalar variable because it's prefixed by a $ sign so if you see a variable named:<br />
<blockquote class="tr_bq">
"$something" </blockquote>
you know that it contains a singular piece of data.<br />
<br />
<br />
Unlike other programming languages (Java), Perl is not strongly typed and is intelligent enough to know that when you have typed a string in quotes, you want it to behave like a string and when you type a number, you want it to behave like a number.<br />
<br />
This means there is no faffing around telling the interpreter what kind of variable you want when it can work it out for itself. All you need to do is tell it what you want the variable to be called and what you want in that variable. Simple<br />
<br />
There are ways of giving the variable a number but wanting it to behave like a string and vice versa but these have to explicitly be done. The default is to treat whatever it is as what it looks like - which sounds very sensible to me but I think there could be some potential problems with this so I guess it needs to be kept in mind.<br />
<br />
<br />
<br />
<b>Declaring and assigning a scalar</b><br />
<b><br /></b>There are two ways to declare and assign a scalar variable; you can either do it all in one go:<br />
<br />
my $name = "Emma";<br />
<br />
or declare and assign separately:<br />
<br />
my $name; #This is declaring the scalar<br />
$name = "Emma;" #This is assigning it<br />
<br />
This has basically said that there is a scalar variable called "name" and the value of this scalar is the string "Emma". The quotes just denote the beginning and the end of the string and won't actually be printed out. If you want to assign a number to a variable, you don't need to put the quotes but more on that later.<br />
<br />
<br />
If we leave 'my' out and we have use strict turned on (which you should have!!), the program will fall to bits when you try to run it and complain at you with something that looks like this:<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">Global symbol "$name" requires explicit package name at declaration.pl line 5.<br />Execution of declaration.pl aborted due to compilation errors.</span></blockquote>
<br />
Not the friendliest of error messages, but I have seen worse. This error message could also mean that you've made a typo when writing a variable name. This will mean having different spellings between the declaration and any usage of it, which will make the interpreter cry.<br />
<br />
<br />
So, now we know how to declare a scalar, the next question is what exactly can we store in these scalars? Posts to follow on numbers and strings...<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/14422352024976746995noreply@blogger.com14tag:blogger.com,1999:blog-5907655605807122632.post-68014212744551713652014-01-16T06:53:00.006-08:002014-01-21T09:07:58.435-08:00Hello World! - writing and running my first print programHmmm what kind of program shall I write first? I wonder if there are any easy start up programs. You know what's coming up...<br />
<br />
<blockquote class="tr_bq">
<table>
<tbody>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">1. </span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>#!/usr/local/bin/perl</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">2.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>use strict;</b></span></td>
</tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">3.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>use warnings;</b></span></td>
</tr>
<tr><td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">4.</span></td><td></td></tr>
<tr>
<td><span style="color: #999999; font-family: Arial, Helvetica, sans-serif;">5.</span></td>
<td><span style="font-family: Arial, Helvetica, sans-serif;"><b>print "Hello World!\n"</b></span></td>
</tr>
</tbody></table>
</blockquote>
<div>
<br /></div>
<div>
and that's it. Really, nothing more. I can now go and run it.</div>
<div>
<br /></div>
<div>
<b>How do I run it?</b></div>
<div>
Easy, there are two different ways you can run a perl script.</div>
<div>
<br /></div>
<div>
1. type "perl filename" into the command line, replacing "filename" with the name of your script including the extension.</div>
<div>
<br /></div>
<div>
2. make the file executable by typing "chmod +x filename" into the command line, again replacing filename with the name of your script including the extension. This command has changed the access permissions to the file and the "+x" means that we have added execution rights for all users. </div>
<div>
We can now run the file in the command line by typing "./filename".<br />
<br />
This now appears on the terminal:<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;"><b>Hello World!</b></span></blockquote>
<br />
<b>What have I actually achieved?</b><br />
This is of course the infamous Hello World script, which is a rite of passage for every programmer learning a new language. This very small 4/5 line script (have you seen this, Java?) has allowed me to print the words in quotes to the console. Print takes a list so you can either give it one thing to print (some text in quotes) or a list of things to print (more than one set of text in quotes separated by a comma). It then stringifies (as it sounds, turns into a string)* the items passed to it, in this case "Hello World!\n". Then this string (or list of strings) is printed to the standard output channel, which I will explain below.<br />
<br />
*not entirely sure how this works but I don't think this post is the place to delve into it. I will do a separate stringy post later on.<br />
<br />
<u>Output Channels</u><br />
When we use the word "print" followed by whatever it is we want to print, it is actually as if we have written "print STDOUT "some text"". STDOUT means that the standard output channel is being used and since this is the default, we don't have to explicitly write it. The standard output channel is directed by default to the terminal screen but this can be changed to a file. There is also another output channel called STDERR, usually reserved for error information, which also is defaulted to go to the terminal screen. This time however, you have to use the whole term "print STDERR" if you want to print to this channel. You will not be able to tell the difference by looking at the output on the screen which text is from the standard output and which is from the standard error channel. To separate these, you can direct one or both of them to separate files. <br />
<br />
This is a link to the print section of the perldocs, if you want to read about it in more detail. I'm personally not advanced enough to understand it all yet.<br />
http://perldoc.perl.org/functions/print.html<br />
<br />
<u>\n</u> <br />
The \n is an indicator to start a new line so if I wrote another print statement in the script, it would appear underneath "Hello World!" in the console.<br />
Note that double quotes must be used for the \n to be interpreted as a newline character. Single quotes would print the whole string literally and "Hello World!\n" would be printed to the console.</div>
Anonymoushttp://www.blogger.com/profile/14422352024976746995noreply@blogger.com2tag:blogger.com,1999:blog-5907655605807122632.post-7770127238170196722014-01-13T03:05:00.000-08:002014-01-21T09:10:11.920-08:00Use Statements and the Whole ShebangSee what I did with the title??.....<br />
Nearly 100% I'm not the first to come up with that.<br />
The shebang and use statements are things that we all put at the top of our perl scripts but do we really know why? Maybe a lot of you do, but I've just been blindly copying and pasting them because I know that my scripts won't work properly without them and it's the right thing to do.<br />
Now I'm actually going to explore what they are for.<br />
<br />
<b>Shebang</b><br />
As far as I can tell shebang is actually a slang word, because why would any normal person come up with that as an official term?<br />
It consists of the characters "#!" and then the path to the interpreter program so the complete shebang line will look similar to the line below:<br />
<br />
<blockquote class="tr_bq">
#!/usr/local/bin/perl</blockquote>
<br />
In fact, in all of the perl code I've seen, which admittedly isn't very much, the shebang has had the <u>exact </u>format as above.<br />
<br />
I've done a little digging to find out what all this actually means.<br />
When a<span style="font-family: Times, Times New Roman, serif;"> script with a shebang is run as a program, the program loader (a part of the operating system that is <span style="background-color: white; line-height: 19.1875px;">one of the essential stages in the process of starting a program</span>) </span>sees the "#!" characters and then parses the rest of the line as an interpreter directive. What does this mean? The interpreter is the thing that executes the script and is specific for each programming language, but the script could be written in any language so we need to know which interpreter is needed. The path points to the location of the interpreter, in this case, the perl interpreter. This means that the Shebang isn't only used in perl, it's used in python, ruby, PHP and other scripting languages.<br />
<br />
<b>Use Statements - also called "Pragmas"</b><br />
<b><br /></b>The most common use statements I've seen are:<br />
<br />
use strict;<br />
use warnings;<br />
use Modern::Perl 2011;<br />
<br />
The last one actually implies use strict and use warnings so you can use it by itself and not have to go through all the bother of writing them separately. But what do they actually mean?<br />
<br />
<b>use strict;</b><br />
This pragma activates three different pragmas:<br />
<br />
<ul>
<li>use strict 'vars'; - this complains when you try to use a variable that you have not previously declared,</li>
<li>use strict 'refs'; - prevents you from using symbolic references*,</li>
<li>use strict 'subs'; - this stops you from using barewords inappropriately, these are words that appear on their own without quotes or other punctuation. For example, with use strict 'subs' activated, my $x = hello; will not be allowed because hello needs to be in quotes.</li>
</ul>
<div>
*I've been looking for ages and I have absolutely no idea what this means! I cannot figure it out. All the explanations I can find just confuse me and talk about concepts that I have no idea about. I guess when I get that far I can come back and fill in this bit.</div>
<div>
<br /></div>
<div>
You can deactivate any of these individual strict pragmas by using "no" rather than "use".</div>
<div>
<br /></div>
<div>
<b>use warnings;</b></div>
<div>
This gives all kinds of debug information, for example typos. It will stop the program from running and tell you the things that you would expect any IDE to. The only thing is that it will only give you one error at a time so you may need to run the script several times to be able to find all the bugs.</div>
<div>
<br /></div>
<div>
You can also activate warnings by typing "-w" in the command line when you run the script.</div>
<br />
<br />
Both the strict and warning pragmas are very useful to have on your perl scripts so it's advisable to include them at the beginning of the script. Alternatively, you can just write "use Modern::Perl 2011;".Anonymoushttp://www.blogger.com/profile/14422352024976746995noreply@blogger.com4tag:blogger.com,1999:blog-5907655605807122632.post-85841838560049621092014-01-10T08:53:00.002-08:002014-01-13T03:44:58.394-08:00Background of PerlAccording to wikipedia, perl is a <span style="font-family: Times, Times New Roman, serif;">"<span style="background-color: white; line-height: 19.1875px;">family of </span><span style="background-color: white; line-height: 19.1875px;">high-level</span><span style="background-color: white; line-height: 19.1875px;">, </span><span style="background-color: white; line-height: 19.1875px;">general-purpose</span><span style="background-color: white; line-height: 19.1875px;">, </span><span style="background-color: white; line-height: 19.1875px;">interpreted</span><span style="background-color: white; line-height: 19.1875px;">, </span><span style="background-color: white; line-height: 19.1875px;">dynamic programming languages</span><span style="background-color: white; line-height: 19.1875px;">. The languages in this family include Perl 5 and </span><span style="background-color: white; line-height: 19.1875px;">Perl 6</span>" </span><br />
<span style="font-family: Times, Times New Roman, serif;"><br /></span><span style="font-family: Times, Times New Roman, serif;"><b>high-level:</b> has strong abstraction from the details of the computer </span><br />
<span style="font-family: Times, Times New Roman, serif;"><b>general-purpose:</b> to be used for writing software for a variety of applications</span><br />
<span style="font-family: Times, Times New Roman, serif;"><b>interpreted:</b> uses an interpreter to execute the code</span><br />
<span style="font-family: Times, Times New Roman, serif;"><b>dynamic:</b> code execution is at run time rather than compile time</span><br />
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<span style="font-family: Times, Times New Roman, serif;">Exciting stuff... Here's some more interesting (I hope) information:</span><br />
<br />
In the short time I've been using perl, I've always wondered where the name actually comes from. I found out that Larry Wall, the creator of Perl just wanted an easy to remember, short word with a nice, positive connotation. It's that simple. Apparently he went through every short word in the dictionary before settling on "Pearl". He then realised before the official release that there was in fact another programming language with the same name already in existence and promptly changed it to the spelling we all know and love - "Perl".<br />
<br />
Perl also has a backronym associated with it (making up a phrase to go with the letters of the word):<br />
<br />
<b>P</b>ractical<br />
<b>E</b>xtraction and<br />
<b>R</b>eporting<br />
<b>L</b>anguage<br />
<br />
I've also discovered that Perl was invented in 1987, before I was born, which definitely excuses me for being way behind.<br />
<br />
<span style="font-family: Times, 'Times New Roman', serif;">Perl is notorious for the ever lengthening time between releases with the last full release being in 1994. In 2000, Larry Wall took suggestions from the perl community for the development of Perl 6 and created documents called "apocalypses" which showed the changes and proposed design based on these suggestions. From what I see, Perl 6 is still just theoretical although there are implementations of it based on the apocalypses. So I guess we're still waiting. Meanwhile Perl 5 is still being updated and at the time of writing, the latest stable release is 5.18.1.</span><br />
<span style="font-family: Times, Times New Roman, serif;"><br /></span>Anonymoushttp://www.blogger.com/profile/14422352024976746995noreply@blogger.com5tag:blogger.com,1999:blog-5907655605807122632.post-2556513543758023812014-01-09T07:35:00.002-08:002014-01-21T09:11:18.625-08:00BeginningI've decided to start this blog because I'm just starting out on my perl journey and I think that I learn the best by writing everything down and explaining it in my own words as if I were explaining it to someone else. I think this is a good way to know that you truly understand something, even Einstein said:<br />
<br />
<blockquote class="tr_bq">
"<span style="background-color: white; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;">If you can't explain it simply, you don't understand it well enough.</span>"</blockquote>
<br />
so this is what I'm hoping to achieve.<br />
<br />
I have done a bit of perl before on my grad scheme. I got the chance to try perl out and this was about six months ago. At the time I was trying to learn quickly so I could get up to speed with everyone else and actually contribute to the team. This meant I started off learning things by heart rather than really understanding what I was writing. Now it's the end of my grad scheme and I have a permanent job in Perl so I want to start from the beginning again and learn things properly because this is now the start of my development career.<br />
<br />
I want to do this properly, which means starting at the very beginning, looking at everything I come into contact with and asking why it's there, what is it's purpose, rather than just accepting it and learning it off by heart without really knowing what it means. I think in this way, I may be learning more slowly but I will be learning completely and understanding everything and hopefully in the future I will be able to pick up Perl concepts more quickly because of this.<br />
<br />
I do have a background in computer science, I have a degree from UCL so I've been programming before for a while with my main language being Java. Now, Java and I haven't really been the best of friends and unfortunately it was what was mostly taught. I did some Prolog, Groovy and a hell of a lot of theoretical stuff - logic, maths etc but mostly Java. I'm not really sure why I didn't get on with it, maybe it's because there's so much faff to get anything working, so much code to write to do on simple thing. Maybe it's because I started off behind everyone else and never really caught up - I don't really know. What I do know is that when I started learning Perl, it seemed to me so much easier to understand and so much easier to get started and make things work.<br />
<br />
I've called this blog "Perl Adventures" because it feels like I'm at the beginning of a very long and slightly overwhelming journey. It's like I've just stepped off the plane and I am in this new world that I can go and explore. I'm not really sure where to start and I'm not really sure what's out there, but I am little bit excited to find out. - That's enough of the cheesy metaphor.<br />
<br />
It's not my main intention, but hopefully I will be able to help other people in the same situation as me.<br />
I'm hoping in this way to shed light on some of the concepts of perl for other people to learn about because I know that finding information about perl isn't the easiest thing in the world. I've often googled a perl term that I don't understand and then been greeted with many more terms I don't understand and then have to google all of those! So maybe if I use the approach of never explaining things with words I don't understand, I can get concepts across that others can really understand.<br />
<br />
Here goes, wish me luck!<br />
<br />Anonymoushttp://www.blogger.com/profile/14422352024976746995noreply@blogger.com2