in reply to Trying to understand Perl :-)

You ask a lot of questions.

sub UNIQUE::print{print 'Hello World!'} UNIQUE->print(333); sub UNIQUE::print{ print "\nMuhahaha! @_ \n"; } UNIQUE->print(65.65.65.65); # Okay this is weird.

First of all, how does 65 become letter 'A' without using chr(65) ?

You're creating a "version string" (see version). Version strings convert the numbers to characters.

Secondly, Perl allows me to redefine my UNIQUE::print and now this second definition overwrites the first one. What happened to the first one???

Perl executes your code in two phases. First it compiles your code. This is when your second declaration of UNIQUE::print overwrites your first declaration. This phase is commonly called the "compile" phase. Then, Perl runs the code. This is when all calls go to the (second) UNIQUE::print function and produce output.

What on earth is this?

sub {5};

It's an anonymous subroutine, that is, a subroutine that you cannot call by name. You usually store it in a variable so that you can access it in other places of your program:

my $five = sub { 5 }; print $five->();

Anonymous subroutines are what makes map and grep useful. Also see Higher Order Perl for a good introduction where anonymous subroutines come in handy.

sub Red { sub LittleRed{'red'}; # sub within a sub LittleRed; # returns 'red' } print "\nPerl is getting confused here..." . Red; print "\n\n"; print LittleRed;
Wait. This is not supposed to work! If I declare a sub within a sub, then the inner sub should not be accessible from the outside. Is this right??? I mean what's the point of declaring a sub within a sub if it's the same as declaring it outside the sub?

Declaring named subroutines within other named subroutines usually is an error. The visibility of subroutine names is global (except for lexical named subroutines, but these are experimental). Declaring nested named subroutines often leads to interesting problems which most often are shown by warnings as Variable %s will not stay shared.

sub Y{ my$i=0; $i while($i++<10); } print"\nYES>".Y;
Now, why is this not printing 10?? When the while loop ends, $i equals 10, so if I just say "$i" then it should use that as a return value for the sub. No?

No. $i is not the expression returned from the last statement. A subroutine evaluates to the value of its last statement.

Is there a way to access previous return values? Example:
sub DDD { 0; 1; 2; 3; 4; 5; } print DDD;

Yes. Use a comma instead of a semicolon (that is, return a list):

sub DDD { 0, 1, 2, 3, 4, 5, }

Replies are listed 'Best First'.
Re^2: Trying to understand Perl :-)
by harangzsolt33 (Deacon) on Jul 28, 2016 at 13:34 UTC
    This is great! Thank you so much for your replies! They were very helpful. Okay, so a little clarification:
    sub ccc{65} print "\n" . ccc.ccc.ccc.ccc; # this evaluates to numbers print "\n" . 65.65.65.65.65; # this evaluates to letters # Ok. It's a little weird, but it is what it is. my $A = sub { print "\nWELCOME! :-) (@_)\n"; 1 }; my $B = sub { print "\nGO AWAY! >:( (@_)\n"; 2 }; my $X = time % 2 ? $A : $B; print $X->(77); $A = 0; $B = 0; $X = 0; # So, if I create anonymous subs, # I can later simply "erase" them? # This is great. # # But now, what happens to my anonymous subroutines? # Do they simply disappear or stay in memory somewhere? print "\n" . __PACKAGE__; print "\n" . __FILE__; print "\n" . __LINE__; print "\n\n"; #sub MY{ my $K = __SUB__; } # Why is this giving me an error? #MY; sub P{(6,7,8)} # returns an array print "\n".(P)[0]; print "\n".(P)[1]; print "\n".(P)[2]; # Makes sense.

      Hi harangzsolt33,

      sub ccc{65} print "\n" . ccc.ccc.ccc.ccc; # this evaluates to numbers print "\n" . 65.65.65.65.65; # this evaluates to letters # Ok. It's a little weird, but it is what it is.

      Well, Perl can tell the difference (on the side, a fun read), and if you know what v-strings are so can you :-) Note that whitespace is significant so that Perl can tell the difference between a v-string and numbers joined with the concat operator ".": print 65 . 65 . 65 . 65; prints "65656565".

      But now, what happens to my anonymous subroutines? Do they simply disappear or stay in memory somewhere?

      I'm not an expert on the internals but I believe they are subject to Perl's normal memory management, i.e. when the last reference to an anonymous sub goes away it is garbage-collected (the memory it used can be reclaimed by Perl). You normally don't need to worry about this, all you need to think about is that when you want a value to go away you make sure to discard all references to it, and that there are no circular references.

      sub MY{ my $K = __SUB__; } # Why is this giving me an error?

      See __SUB__: "This token is only available under use v5.16 or the current_sub feature. See feature."

      sub P{(6,7,8)} # returns an array

      This may seem nitpicky, but it's a common pitfall: that's not an array, that's a list. Note that return, including the implicit return value, passes along the context that the sub was called in. Your sub P, when called in list context (for example, when its return value is assigned to an array), will return the three values 6,7,8, and you won't be able to tell the difference between it and a sub Q { my @a = (6,7,8); @a } called in list context.

      However, you will be able to tell the difference when you write my $x = P; my $y = Q;: $x will contain 8 (the last value from the list), and $y will contain 3 (the number of items in the array)*. The reason is that sub P being called in scalar context causes its return value to be evaluated in scalar context, and the Comma Operator in scalar context "evaluates its left argument, throws that value away, then evaluates its right argument and returns that value." In sub Q, the return value @a evaluated in scalar context returns the number of elements of the array, the normal behavior of an array in scalar context.

      * By the way, a debugging tip: don't test code like this with arrays that contain numbers; use strings instead. You wouldn't have been able to tell the difference between $x and $y if the returned list had been (1,2,3).

      Hope this helps,
      -- Hauke D

      Please put your text in between <p>...</p> tags, and your code in between <code>...</code> tags. Writing your questions as stream-of-consciousness comments makes your post very unpleasant to read to me.

      Perl manages all memory through reference counting, so you can release most memory by not holding any reference to it anymore.

      If your question is "Why is this giving me an error", you will find it usually helps us help you much better if you explicitly show the verbatim error that Perl shows.