What the Llama taught me? Part – 1

Yesterday I finished reading the Llama book. I need to go through the book again since I didn’t get a thorough understanding of all the contents especially the last chapters. Any how I got a glimpse of what Perl could do and I’m so amazed by most of what it could do, that I ordered 4 books of the Internet, the Llama, Alpace, Vicuna and Camel (The Llama I hold now is a friend’s copy).

Here are some of the new constructs I learned in Perl and some others which are there in other languages but treated differently in Perl. (NB: I have only recently started learning Perl and my experience is litle. So these are what I understood, may be some are not perfectly right. But If some one points out so, I’m willing to correct my entry.)

I believe a newbie can read this and get a bird’s eye view of Perl before getting hold of a Llama.

1) There are no integers. All numerals are treated like floating point by Perl. So 10/3 yields 3.3333… always. However in the case of ‘%’ floats are converted to integers (I’m not sure how Perl makes this possible as there isn’t an integer in Perl, or so I’m said, Some one may give an explanation in comments.).

2) Underscores can be used to add clarity to integer literals.
eg : 12_345_678 is equal to 12345678

3) Principle of “no built-in limits“. eg: You string length can range from 0 to infinity(meaning how much your memory can hold).

4) String repetition operator ‘x’.
eg: "Chris" x 3 is ChrisChrisChris.
Once again here too, if the right operator is a float it is truncated to corresponding integer value.

5) The block curly braces are ALWAYS needed around the conditional code. This is some kind of an inconvenience compared to C rule of no need for the braces if condition is followed by a single line. I believe this is made compulsory to aid readability.

6) The use of an uninitialized variable doesn’t yield a fatal error. Uninitialized variables are pre initialized with a special value ‘undef’, which acts like ‘0’ in numeric context and as empty string in string context. Using the ‘warnings’ pragma will sometimes arise a warning about the use of ‘undef’ values’. There is a defined() function to check whether a variable is defined.

7) There is no need to declare the aray size. It can grow up to whatever size it like. If you declare $fred[999] = 'somevalue' for an array @fred which earlier had only 2 members, the above code would extend the array to 1000 elements with all the elements from $fred[2] to $fred[998] as ‘undef’.
Also you can index the array with a float number(It isn’t an error, but will be truncated) so $fred[2.324] means $fred[2]. You can even use the above said technique of ‘underscores’ to denote an array inex. eg $fred[123_456]
The last array index can be found out by $#fred. Also you can use negative array index to access the array from end. eg $fred[-1] is equal to $fred[$#fred].

8 ) The list literals are  great innovation. The range operator (..) and qw shortcut are great way to ease the coding. [NB: The range operator only counts uphill , there is a reverse function for the opposite.]
The list assignments is an easy way to assign values.

9) The list construct makes it easy to swap two variables easily, that too without a third variable.
eg: ($fred, $barney) = ($barney, $fred) # This swaps the contents of the two variables.
Wow! What an idea!. That’s why I said list is indeed an innovation. There are more techniques like these in lists. When working with lists you will feel that Perl has got artificial intelligence of some sort. It knows to discard values when the two sides of the equal signs aren’t balanced.(Actually as a matter of fact, there are a lot of places where we feel Perl has got AI built in. May be it’s the reason why people complain Perl is hard. Here we are dealing with a beast which has got brains of it’s own. So it’s quite natural to need brains to tame it)

10) push, pop, shift, unshift etc are some array operators which makes life easy while working with arrays.

11) Once again a portion, where Perl shows intelligence. It knows whether you are talking in scalar or list context. So we also need to be intelligent enough to know the context while talking with Perl.
eg : reverse in list context gives the list from the last member whereas n string context reverses the string. You can force a list to scalar context by explicitly using the scalar keyword.

12) Sub routines in Perl is a section where there is a lot of astonishments in store for a newbie. The usual method of calling a subroutine is &<sub routine name>, but it is not always so. If Perl can understand it is a function call somehow then you can use a simple <sub routine name>. This means if the sub routine definition is provided in the code before the call or if there are parameters in the function call(If there are parameters, it ought to be a function, cool logic. isn’t it.?). Now even the skeptics among you can believe my claim ‘Perl is intelligent’.

13) There may or may not be return in a function. If there isn’t a return, the result of the last executed line of code is the return value (Please make sure you understand correctly what is returned since in the earlier days of Perl this can rise a lot of troubles)

14) There are multitude of default variables like $/, $_ etc which maybe confusing at first but once start to get going, these makes life more easy. for eg: $_ default variable makes it possible to write the foreach loop like
foreach (1..10) {
print($_);
}

instead of
foreach $num (1..10) {
print($num);
}

both of the print the numbers from 1 to 10, but the former one may be easier to write. You may decide which one you should use. If you find the second one more readable or say more in tandem with your foreach constructs in other languages go for the second.

15) I have been saying this for a while but even the motto for Perl is ‘There is more than one way to do it’. Do you know we can even write the for instead of the foreach in the above example.

There is more I can say, but I read somewhere the attention span of the average reader diminish by 70% after the first 15 points , so I’m reserving the rest of it for another post.

So here is what to emphasize before the small break.

So Perl is an intelligent beast which is wild(read as powerful) but yet domesticable(suits even the beginner) [Can you find a similarity with camel?]. If you are in any doubt, please try it, and be amazed.

add to del.icio.us : Add to Blinkslist : add to furl : Digg it : Stumble It! : add to simpy : seed the vine : : : TailRank : post to facebook

20 thoughts on “What the Llama taught me? Part – 1

  1. Perl does have integers. A scalar (SV) can hold integers (IV), floating point numbers (NV), strings (PV), and references (RV): (http://perldoc.perl.org/perlguts.html#What%27s-Really-Stored-in-an-SV?). Integers and floating point numbers are freely converted into each other. Most math operators work on floating point numbers by default, but you can use the integer pragma (http://perldoc.perl.org/integer.html) to instruct Perl to use integer semantics (e.g. 5/2 == 2) for the current scope.

    1. Yeah we can use the modifier, that is a new construct I want to talk in the second part of the post, but that doesn’t rule out the ALWAYS option in the normal if case.

  2. On point 12, you almost never call a function with a leading &. That is the only part of the Llama that I hate. Calling a function with a leading & has magical behavior you usually don’t want. I have had arguments with d foy and Schwartz over it. Teaching beginners to call functions that way is a great disservice in my opinion.

      1. brian d foy said:

        [He is reading] _Learning Perl_, and he hasn’t got to the point where we tell the reader they don’t need the & in front of subroutine calls. Most of the progression goes from the general rule to the usual case.

        I don’t find his argument compelling as I don’t consider &foo() the general rule, but more of an exception to the general case that has magical behavior.

  3. You should start doing use strict; at the top of your code. It *will* give you errors if you do something silly like:

    my $foo = 5;
    print $f0o;

    also note the “my”; when you use strict you must put my in front of your variables. If you want a global use our, but in general you probably don’t need that.

    1. Christy, nice post, for a newbie to perl like me.

      fREW Schmidt, wouldn’t be using “use warnings;” are more gentle to newbies because i have tried a few times turning on “use strict;” and it throw a bunch of errors to me which i dont understand it. Rather, using “use warnings;”, the suggestions are more gentle and easier to understand.

      just my 2 cents.

      1. Hi, Psybermonkey,
        Thanks. Yeah, I agree ‘use strict;’ construct can sometimes lead a newbie in the path of oblivion. But after first 10 hours or so with Perl, you should immediately start using it. It is Perl’s way of using local variables. It can save you a lot of hassles. Like in the times fREW Schmidt told.
        The ‘use warnings;’ construct aids in a different way. It mainly helps you in the case of syntax errors and so. For greater detail you can also use ‘use diagnostics;’.
        People always use the strict and warnings/diagnostics pragma together.

  4. On point 14, You should use the default variable with other constructs that use the default variable, and only contiguously so. Explicitly naming $_ outside of grep or map removes some of its value. And counting on $_ to stay the same value (since it is global) is dangerous. That is why I state that it should only be used in contiguous statements that work with it:

    while () {
    chomp;
    my @rec = split /,/;
    #do stuff with @rec
    }

    while () sets $_
    chomp modifies it
    and split uses it
    after that point you should no longer trust $_.

      1. A good rule of thumb that I like to follow is that you should only use $_ in situations where you don’t have to type it out (as Chas. Owens pointed out in his response above). In any other case, using a localized variable is in my opinion cleaner and clearer.

  5. 7) If you do:

    my @fred = ();
    $fred[999] = ‘somevalue’;

    then $fred[0..998] do not exist.

    #!/usr/bin/perl

    use strict;
    use warnings;

    my @fred = ();
    $fred[9] = ‘somevalue’;

    for my $i ( 0 .. $#fred ){
    if( exists $fred[$i] ){
    if( defined $fred[$i] ){
    print “\$fred[$i] exists, is defined, and has value $fred[$i]\n”;
    }else{
    print “\$fred[$i] is not defined\n”;
    }
    }else{
    print “\$fred[$i] does not exists\n”;
    }
    }

    13) Always have a return statement for your sub’s. That way you always know what is returned.

    sub foo {
    return;
    }

    If foo() is called in a scalar context, undef is returned. If it is called in a list context, the empty list, (), is returned.

    sub bad_return {
    return undef;
    }

    In a list context, this will return a list of one element: ( undef ) This is not the empty list.

    14) All the special Perl variables can be found here: http://perldoc.perl.org/perlvar.html

    Plus:

    Always `use strict;` It will cause a fatal compile error for most things you do not want to do.

    1. Ok, it’s showing “Use of uninitialized value within @fred in print at….”. The Llama said “If Perl needs to create the intervening elements, it creates them as undef values.”. So here should I understand that Perl didn’t find it useful to create the intervening elements, or isn’t this same as undef?

      1. No, they’re not the same. This is the point I’m trying to make. In this case, the book is wrong; intervening values do not exist.

        This is a problem that is more pronounced with hashes. It is possible for a hash key to exist but have an undefined value. The general rule is: use define() to test for array elements and use exist() to test for hash elements.

  6. @shawncorey In that case some one should point this out to one of the authors. The book is in it’s 5th edition and I can’t believe this went unnoticed till now.

Leave a reply to fREW Schmidt Cancel reply