Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Can I embed subroutines?

96 views
Skip to first unread message

T

unread,
Aug 1, 2015, 3:39:10 AM8/1/15
to
Hi All,

If I want a second subroutine to only be used the first
subroutine, can I put it inside the first? Or am, I
thinking in Modula2 again?


sub A {
sub B {};
calling B with something
};

Such that B can only be called from inside A?


Or do I have to make them linear so everyone can see B
(which I don't want)?

sub B {};
sub A {};

Many thanks,
-T



C.DeRykus

unread,
Aug 1, 2015, 4:15:10 AM8/1/15
to
It's possible via a lexical variable that stores an anonymous func. ref:


sub A { ...; my $B=sub{...}; $B->(); ... }

This technique is described in the perl docs. See: perldoc perlsub

--
Charles DeRykus

Jens Thoms Toerring

unread,
Aug 1, 2015, 4:23:58 AM8/1/15
to
T <T...@invalid.invalid> wrote:
> If I want a second subroutine to only be used the first
> subroutine, can I put it inside the first? Or am, I
> thinking in Modula2 again?

> sub A {
> sub B {};
> calling B with something
> };

Try it out and you will find that it works.

> Such that B can only be called from inside A?

Now that's something that doesn't work - even if B()
is defined within A() it still can be called from
the outside. If you just wan't to avoid poluting the
namespace I'd go for a package - but that also doesn't
keep someone from calling anything in it.

Perl tends not to enforce such kind of "private ownership"
of functions (or object attributes etc.) as many other
languages do. As it's said in "Perl Programming":

A module would prefer that you stay out of its
living room because you weren't invited, not be-
cause it has a shotgun.

Regards, Jens
--
\ Jens Thoms Toerring ___ j...@toerring.de
\__________________________ http://toerring.de

T

unread,
Aug 1, 2015, 4:42:57 AM8/1/15
to
Thank you!

T

unread,
Aug 1, 2015, 4:43:05 AM8/1/15
to
Thank you!

T

unread,
Aug 1, 2015, 4:59:01 AM8/1/15
to
On 08/01/2015 01:23 AM, Jens Thoms Toerring wrote:
> Now that's something that doesn't work - even if B()
> is defined within A() it still can be called from
> the outside.

So Perl not so picky. :-)

Rainer Weikusat

unread,
Aug 1, 2015, 8:13:03 AM8/1/15
to
j...@toerring.de (Jens Thoms Toerring) writes:
> T <T...@invalid.invalid> wrote:
>> If I want a second subroutine to only be used the first
>> subroutine, can I put it inside the first? Or am, I
>> thinking in Modula2 again?
>
>> sub A {
>> sub B {};
>> calling B with something
>> };
>
> Try it out and you will find that it works.
>
>> Such that B can only be called from inside A?

[...]

> Perl tends not to enforce such kind of "private ownership"
> of functions (or object attributes etc.) as many other
> languages do. As it's said in "Perl Programming":
>
> A module would prefer that you stay out of its
> living room because you weren't invited, not be-
> cause it has a shotgun.
>
Perl doesn't support lexically scoped declarations except when using
my. Consequently, nesting B in A in the way above is just an
obfuscation: The subroutine will still have a name in the symbol table
of the current package.

Rainer Weikusat

unread,
Aug 1, 2015, 9:53:00 AM8/1/15
to
j...@toerring.de (Jens Thoms Toerring) writes:

[...]

> A module would prefer that you stay out of its
> living room because you weren't invited, not be-
> cause it has a shotgun.

A Perl module isn't really a module in the sense the term is used in
Modula but rather what's called 'a package' in Lisp (and the keyword
used for declaring one is 'package' and not 'module'): A collection of
(usually) related named things which is linked into a global,
hierarchically structured namespace.

This is implemented as set of nested hash tables: The top-level symbol
table is %:: (or %main::) and it contains a key Package:: for every
top-level package named Package. The hash-slot of the corresponding glob holds a
reference to the symbol table (hash) for the package. And so forth for
nested packages.

Two ways to get access to the coderef corresponding with a subroutine
defined in a nested package:

------------
package Something;

package Something::Else;

sub inc { $_[0] + 1 }

package main;

my ($inc0, $inc1);

$inc0 = \&Something::Else::inc;
$inc1 = \&{$::{'Something::'}->{'Else::'}->{inc}};

print("$inc0, $inc1\n");
------------

Eric Pozharski

unread,
Aug 1, 2015, 1:33:50 PM8/1/15
to
with <mphsvs$d86$1...@dont-email.me> T wrote:

*SKIP*
> sub A {
> sub B {};
> calling B with something
> };
> Such that B can only be called from inside A?

You can do things like this with 5.20 (or something). Yes, I understand
your motivation to stay with ancient perl.

> Or do I have to make them linear so everyone can see B (which I don't
> want)?

Even with your ancient perl you can achieve this (and there will be
dragons). Please consume

perldoc perlref

*CUT*

--
Torvalds' goal for Linux is very simple: World Domination
Stallman's goal for GNU is even simpler: Freedom

T

unread,
Aug 1, 2015, 4:58:25 PM8/1/15
to
Got it. Thank you!

Mart van de Wege

unread,
Aug 1, 2015, 6:00:09 PM8/1/15
to
In case of subs it isn't, indeed.

The rule is simple: named subs are always entered in the top level of
the package they're defined in. Anonymous subs appear only in the scope
they're defined in.

It's essentially the same mechanism as Common Lisp's defun and lambda
forms.

I'm going to post a bit of intermediate Perl that may be confusing. If
you don't get it, just save it and wait until you're further along,
don't try to understand it in one go. However, since it is a fairly
common technique in lexically scoped languages like Perl, you should
learn it sooner or later.

If an anonymous sub is defined within an enclosing scope, and a
reference to that sub is returned to outside that scope, then the sub
will continue to exist outside that scope, with all lexicals still bound
to it; this is called a closure.

The canonical example is a counter:

sub make_counter {
my $count = 0
return sub { $count++ } # Return an anonymous sub that increases
# $count every time it is called.
}
my $counter = make_counter(); # $counter now contains a reference to an
# anonymous sub, with its own private copy
# of $count.
# Execute the anonymous sub 10 times and print the result
for (1..10) {
print $counter->() # The deference operator -> executes a sub
# reference held in the left-hand side argument
# with the arguments between parenthesis.
}

the 'my $count' lexical variable normally would disappear after
make_counter is done executing; however, the anonymous sub returned from
that function will retain a binding to a private copy of $count, and
refer to that every time it is called.

This, as you may surmise, is also the way to make variables fully
private; never expose the variable, just return closures referring to
it.

Mart
--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.

T

unread,
Aug 2, 2015, 5:13:17 AM8/2/15
to
Hi Mart,

Thank you!

I am going to copy it down and save it!

Questions:

1) What does the ++ on $count++ do?

2) What am I looking at:
return sub { $count++ }

Is "{ $count++ }" the name of the sub? Are you passing
a pointer to another sub that is not showing here?

3) In Modula2,

sub make_counter {
my $count = 0
return sub { $count++ }
}

"$count" would vanish after the subroutine was exited.
Is this not the case in Perl?

4) in your do loop
for (1..10) { print $counter->() ...

do I presume correctly that 1 through 10 by 1 is
substituted in the "()" for each iteration?

5) your statement:
The deference operator -> executes a sub
reference held in the left-hand side
argument with the arguments between parenthesis.

I only see a variable "$counter" on the left side
(unless you are referring "print"). By chance are
you passing a pointer to another sub in a variable?
(I use to do this a lot in Modula2. Be nice to have
that capability back.)

6) would this be a good read for me?
Lexical vs. Package Variables:
http://www.perlmonks.org/?node_id=95813

7) what the h*** is a lexical environment? I have
DuckDuckgo'ed it and get tons of stuff that is too
advanced for me to understand. Do you know of
a good link?

8) is this the same thing you are speaking of?
https://en.wikipedia.org/wiki/Lexical_analysis


-T

I may ask you some more questions about it when
the hour is not so late.

Rainer Weikusat

unread,
Aug 2, 2015, 6:27:12 AM8/2/15
to
Mart van de Wege <mvd...@gmail.com> writes:
> T <T...@invalid.invalid> writes:
>> On 08/01/2015 01:23 AM, Jens Thoms Toerring wrote:
>>> Now that's something that doesn't work - even if B()
>>> is defined within A() it still can be called from
>>> the outside.
>>
>> So Perl not so picky. :-)
>
> In case of subs it isn't, indeed.
>
> The rule is simple: named subs are always entered in the top level of
> the package they're defined in. Anonymous subs appear only in the scope
> they're defined in.

As Eric Pozharski pointed out, this isn't really true anymore for
sufficiently current perls: Since 5.18, the Perl compiler supports
lexcically-scoped, named subroutines as an experimental feature. As far
as I could determine from the documentation, this means that

my sub x10 { $_[0] * 10 };

will be translated into an equivalent of

my $x10 = sub { $_[0] * 10 };

and invocations of x10 in the corresponding lexical scope will call this
subroutine.

I consider this of limited usefulness because it doesn't scale much
beyond one level of nesting for text-formatting reasons and I consider
the idea that 'enforced information hiding' is necessary to stop the
morons from stepping onto the grass in place they're not supposed to
misguided --- said morons (who doubtlessly exist in droves) will find
another way to cause mayhem and an attempt to teach them something about
'enlightened self interest' would seem more useful to me.

Mart van de Wege

unread,
Aug 2, 2015, 6:56:07 AM8/2/15
to
T <T...@invalid.invalid> writes:

> Questions:
>
> 1) What does the ++ on $count++ do?
>
Like in C, the ++ operator increments its argument.

> 2) What am I looking at:
> return sub { $count++ }
>
> Is "{ $count++ }" the name of the sub? Are you passing
> a pointer to another sub that is not showing here?
>
As said, the sub does not have a name, it's anonymous. Return returns a
reference to a piece of code.

> 3) In Modula2,
>
> sub make_counter {
> my $count = 0
> return sub { $count++ }
> }
>
> "$count" would vanish after the subroutine was exited.
> Is this not the case in Perl?
>
Normally, yes. Unless something still has gotten hold of it, like an
anonymous subroutine in the example above, which will retain a private
copy and can keep referring to that.

> 4) in your do loop
> for (1..10) { print $counter->() ...
>
> do I presume correctly that 1 through 10 by 1 is
> substituted in the "()" for each iteration?
>
Nope.

The for loop does not have a loop variable, so it just iterates ten
times over the list and executes the block.

It's the $count++ that increments the private copy of $count; and
returns the current value of that private copy.

> 5) your statement:
> The deference operator -> executes a sub
> reference held in the left-hand side
> argument with the arguments between parenthesis.
>
> I only see a variable "$counter" on the left side
> (unless you are referring "print"). By chance are
> you passing a pointer to another sub in a variable?
> (I use to do this a lot in Modula2. Be nice to have
> that capability back.)
>
Yes. That's called a reference in Perl. $counter holds a reference to an
unnamed piece of code, an anonymous sub (and in this case a special kind
of anonymous sub, a closure).

> 6) would this be a good read for me?
> Lexical vs. Package Variables:
> http://www.perlmonks.org/?node_id=95813
>
That's a pretty good start to describe Perl's scoping rules.

> 7) what the h*** is a lexical environment? I have
> DuckDuckgo'ed it and get tons of stuff that is too
> advanced for me to understand. Do you know of
> a good link?
>
Deary me. I understand that, but I am at a loss to put it in easily
understandable words.

> 8) is this the same thing you are speaking of?
> https://en.wikipedia.org/wiki/Lexical_analysis
>
Heck no, that's part of parsing source.

This is better:
https://en.wikipedia.org/wiki/Scope_%28computer_science%29#Lexical_scoping
https://en.wikipedia.org/wiki/Closure_%28computer_programming%29

>
> -T
>
> I may ask you some more questions about it when
> the hour is not so late.

Don't. It is still a way above your level. Just save this subthread and
revisit it later.

Rainer Weikusat

unread,
Aug 2, 2015, 7:24:19 AM8/2/15
to
T <T...@invalid.invalid> writes:

[...]

> 7) what the h*** is a lexical environment? I have
> DuckDuckgo'ed it and get tons of stuff that is too
> advanced for me to understand. Do you know of
> a good link?

In Perl, it would refer to the set of 'currently accessible my-things',
eg, in

---------
sub make_fibber
{
my ($v0, $v1);

return sub {
my $next = $v0 + $v1 || 1;

$v0 = $v1;
$v1 = $next;

return $next;
};
}

my $fibber = make_fibber();

print($fibber->(), "\n") for 0 .. 15;
---------

The 'lexical environment' of the closure calculating the numbers
consists of the my-variables $v0 and $v1.

T

unread,
Aug 3, 2015, 10:04:35 PM8/3/15
to
What does "$fibber->()" mean?

Mart van de Wege

unread,
Aug 4, 2015, 2:42:07 AM8/4/15
to
T <T...@invalid.invalid> writes:

>
>
> What does "$fibber->()" mean?

It means 'call the subroutine reference in $fibber and pass it the
values between ()'.

T

unread,
Aug 4, 2015, 3:09:40 AM8/4/15
to
On 08/03/2015 11:30 PM, Mart van de Wege wrote:
> T <T...@invalid.invalid> writes:
>
>>
>>
>> What does "$fibber->()" mean?
>
> It means 'call the subroutine reference in $fibber and pass it the
> values between ()'.
>
> Mart
>

I am not following. :-[

Mart van de Wege

unread,
Aug 4, 2015, 4:28:07 AM8/4/15
to
You can take a reference to a subroutine and assign it to a
variable. The way to execute it later is to apply the -> operator to
that variable.

Try this:

use strict;
use warnings;

my $sub_example = sub {
my $arg = shift;
print "anonymous sub executing now with argument $arg.\n";
}
$sub_example->("foo");


$sub_example is assigned a reference to an anonymous sub; it now
contains a code reference. To execute it, you use the -> operator, with
the arguments to the anonymous sub in the list on the right hand
side. If the sub takes no argument, you pass it an empty argument list
(), this is mandatory, because -> is not a unary operator, it *needs* a
right-hand side.

See perldoc perlop, "The Arrow Operator" for details.

Rainer Weikusat

unread,
Aug 4, 2015, 6:00:35 AM8/4/15
to
T <T...@invalid.invalid> writes:
> On 08/03/2015 11:30 PM, Mart van de Wege wrote:
>> T <T...@invalid.invalid> writes:
>>
>>>
>>>
>>> What does "$fibber->()" mean?
>>
>> It means 'call the subroutine reference in $fibber and pass it the
>> values between ()'.
>
> I am not following. :-[

Why don't you run the code instead of wondering about it? You can follow
the control flow by inserting print statements or you can run it
interactively using the Perl debugger (perl -d)?

NB: This is something I consider a simple example but that doesn't mean
it's simple to you, especially since it likely involves concepts (such
as closures and lexical environment) you're not very familiar with.

Rainer Weikusat

unread,
Aug 4, 2015, 6:11:56 AM8/4/15
to
What does this question mean? At the highest level, it's 'calculcate
the next Fibonacci number and return it'. Somewhat below, $fibber is
Perl scalar with a name which is a silly wordplay on 'fibonacci number
producer'. It holds the return value of make_fibber which is a reference
to a subroutine which will caluclate the next Fibonacci number and
return it whenever it is invoked (a so-called generator although other
people prefer the term iterator[*]). That's a simple example for
something working in a "non-null lexical environment" because it needs
the two most recently calculated numbers in order to do that (stored in
$v0 and $v1). Lastly,

$fibber->()

calls this subroutine. '->' is another way to get from a reference to
something to this something. It could also have been written as

&$fibber()

or even

&$fibber

George Mpouras

unread,
Aug 4, 2015, 5:36:03 PM8/4/15
to
On 1/8/2015 10:39, T wrote:
> ly be called from inside A?
>

of course you can embed subroutines recursive , for ever ... here is how
to do it




use strict; use warnings; use feature 'say';

no warnings "experimental::lexical_subs";
use feature 'lexical_subs';

my sub foo { 'outer local foo' }
our sub bar { 'outer global bar' }

Sabroutine();

sub Sabroutine
{
# call the outer bar
say bar();

my sub bar { 'inner local bar' }

# call the inner bar
say bar();

# call the outer bar
say &main::bar();
}





Jens Thoms Toerring

unread,
Aug 6, 2015, 7:52:55 PM8/6/15
to
T <T...@invalid.invalid> wrote:
> On 08/03/2015 11:30 PM, Mart van de Wege wrote:
> > T <T...@invalid.invalid> writes:
> >
> >> What does "$fibber->()" mean?
> >
> > It means 'call the subroutine reference in $fibber and pass it the
> > values between ()'.

> I am not following. :-[

It's probably a lot simpler to intuitively grok what things
like this mean if you have a background in C - quite a bit
of Perl's syntax is derived from C. And if you know C you'll
feel comfortable with pointers.

The most trivial notion of what a pointer is is that it's just
a variable with the address of something else. That's in part
correct and part short of the mark: a pointer isn't just a
memory address but also carries information about the type of
what's pointing to. You can have pointers to integers, poin-
ters to floating point numbers, pointers to strings, pointers
to functions (or even pointers to pointers) - and what it
points to makes a difference in how it can be used (though,
in C a pointer also can be "reduced" to a mere adress if
needed for some reasons).

Perl extends this concept a bit further and thus calls pointers
'references'. E.g., in C a pointer to an array is just a pointer
to the first element of the array and does not carry also the
information about the size of the array, while a Perl reference
to an array contains that additional information.

Perl also uses the '->' operator from C. In C it's only used in
connections with so-called structures, which are basically just
collections of data fields with names. In C you may have e.g.

struct MyStruct {
int x;
double y;
};

That's a user-defined type, here a collection two data fields,
one for an integer, named 'x', and one for a floating point
value, named 'y'. If you need an instance of such a structure,
named 'z', you'd write

struct MyStruct z;

You then can assign to the fields of 'z' with e.g.

z.x = 42;
z.y = 3.14159265359;

Of course, you can also create pointers to instances of such
tructures - you'd create one to 'z' by writing

struct MyStruct * pz = &z;

This is just saying 'pz' is a new variable that is a pointer
to a struct of type MyStruct, and it's initialized to the
address of 'z' ('&' in this context being the "address ope-
rator" - similar to how the backslash is used in Perl for
creating a reference).

Now, given such a pointer to a structure, how do you get at
its data fields? The most convenient way is to use the '->'
operator. So if you want to change the integer field called
'x' of the MyStruct structure pointed to by 'pz' you can
write

pz->x = 17;

And Perl has incorporated that concept (and did run with it,
boldly using it in places never considered in C): whenever
you have a reference to something with an "inner structure"
you can use '->' to get at the innards of what the reference
is referencing.

The simplest example is probably an array:

my @arr = ( 1, 2, 3 );
my $arr_ref = \@arr;
print $arr_ref->[ 0 ], "\n";

This is going to print out the first element (with index 0)
of the array '$arr_ref' is a reference to.

The same works for hashes:

my %hash = ( good => 1,
bad => 0 );
my $hash_ref = \%hash;
print $hash_ref->{ good }, "\n";

And when '$fibber' (that's what started the whole discussion)
is a reference to a function, then

$fibber->( );

is just a call (with no arguments) of the function '$fibber'
is a reference to. So you can do things like this

sub foo {
my $a = shift;
print "In function foo, called with argument $a\n";
}

my $foo_ref = \&foo;
$foo_ref->( 'bla' );

This may look arcane (or even useless;-) at the moment, but
there's a lot of places all this can be very handy.

T

unread,
Aug 7, 2015, 7:20:49 PM8/7/15
to
On 08/04/2015 03:00 AM, Rainer Weikusat wrote:
> Why don't you run the code instead of wondering about it?

I am as I write this. It has syntax errors.

T

unread,
Aug 7, 2015, 7:24:01 PM8/7/15
to
On 08/06/2015 04:52 PM, Jens Thoms Toerring wrote:
> Perl extends this concept a bit further and thus calls pointers
> 'references'. E.g., in C a pointer to an array is just a pointer
> to the first element of the array and does not carry also the
> information about the size of the array, while a Perl reference
> to an array contains that additional information.

Hi Jens,

Wonderful way of stating it. Very clear. The word "pointer"
can have a specific and a general meaning. Relating this to
"C" was beautiful.

By the way in Modula2, a pointer just points to the first element.

-T

T

unread,
Aug 7, 2015, 7:33:35 PM8/7/15
to
On 08/06/2015 04:52 PM, Jens Thoms Toerring wrote:
Extraordinary tutorial! Thank you!

Follow up question: in your example:
my @arr = ( 1, 2, 3 );
my $arr_ref = \@arr;
print $arr_ref->[ 0 ], "\n";

Would these two be the same thing?

print $arr_ref->[ 0 ], "\n";
print $$arr_ref[ 0 ], "\n";

-T




T

unread,
Aug 7, 2015, 7:55:26 PM8/7/15
to
On 08/04/2015 01:19 AM, Mart van de Wege wrote:
> T <T...@invalid.invalid> writes:
>
>> On 08/03/2015 11:30 PM, Mart van de Wege wrote:
>>> T <T...@invalid.invalid> writes:
>>>
>>>>
>>>>
>>>> What does "$fibber->()" mean?
>>>
>>> It means 'call the subroutine reference in $fibber and pass it the
>>> values between ()'.
>>>
>>> Mart
>>>
>>
>> I am not following. :-[
>
> You can take a reference to a subroutine and assign it to a
> variable. The way to execute it later is to apply the -> operator to
> that variable.
>
> Try this:
>
> use strict;
> use warnings;
>
> my $sub_example = sub {
> my $arg = shift;
> print "anonymous sub executing now with argument $arg.\n";
> }

You forget the semicolon

> $sub_example->("foo");
>
>
> $sub_example is assigned a reference to an anonymous sub; it now
> contains a code reference. To execute it, you use the -> operator, with
> the arguments to the anonymous sub in the list on the right hand
> side. If the sub takes no argument, you pass it an empty argument list
> (), this is mandatory, because -> is not a unary operator, it *needs* a
> right-hand side.
>
> See perldoc perlop, "The Arrow Operator" for details.
>
> Mart
>

Hi Mart,

Thank you!

-T


<code>
#!/usr/bin/perl

use strict;
use warnings;

# Note: the sub doesn't get a name, just a "reference" address, which
# fortunately does have a name.

my $AnonPtr = sub ( $ ) {
my $arg = shift; # shift Shifts the first value of the array off
and returns it
print "anonymous sub executing now with argument $arg.\n";
};


$AnonPtr->( "foo" );
</code>

$ VariableAsSubTest.pl
anonymous sub executing now with argument foo.


T

unread,
Aug 7, 2015, 7:56:03 PM8/7/15
to
Hi Mart,

Fascinating. Thank you!

-T



Jens Thoms Toerring

unread,
Aug 7, 2015, 8:20:47 PM8/7/15
to
T <T...@invalid.invalid> wrote:
> Follow up question: in your example:
> my @arr = ( 1, 2, 3 );
> my $arr_ref = \@arr;
> print $arr_ref->[ 0 ], "\n";

> Would these two be the same thing?

> print $arr_ref->[ 0 ], "\n";
> print $$arr_ref[ 0 ], "\n";

Yes. And you can also do it with

print @$arr_ref[ 0 ], "\n";

As usual in Perl, there's more than one way to do it. Can
become confusing at times, admittedly;-)

T

unread,
Aug 7, 2015, 9:08:36 PM8/7/15
to
Found the missing semicolon

T

unread,
Aug 7, 2015, 9:27:26 PM8/7/15
to
On 08/07/2015 05:20 PM, Jens Thoms Toerring wrote:
> T <T...@invalid.invalid> wrote:
>> Follow up question: in your example:
>> my @arr = ( 1, 2, 3 );
>> my $arr_ref = \@arr;
>> print $arr_ref->[ 0 ], "\n";
>
>> Would these two be the same thing?
>
>> print $arr_ref->[ 0 ], "\n";
>> print $$arr_ref[ 0 ], "\n";
>
> Yes. And you can also do it with
>
> print @$arr_ref[ 0 ], "\n";
>
> As usual in Perl, there's more than one way to do it. Can
> become confusing at times, admittedly;-)
>
> Regards, Jens
>


Hi Jens,

Thank you! I just included it in my notes.

Just out of curiosity, how are you getting away with addressing
an element in an array with "@"

print @$arr_ref[ 0 ], "\n";

Where ever I do it I get the finger shaken at me.

$ perl -e 'use strict; use warnings; my @A=(11,22,33); print "@A[2]
\n";'

Scalar value @A[2] better written as $A[2] at -e line 1.
33


It is a real pain in the butt, as it is intuitive to me
to address a value in an array with the array symbol.
And I have to go back over everything and change them.

Well, right after I insert all the missing semicolons
Bash doesn't use a semicolon at the end the line but
does use them to break up command like Perl does. I
wonder if next time I do some more Bash programming
if I will start putting semicolons at the end of each
line. Pavlovian response.

Thank you for the help!
-T (a.k.a. Todd)


T

unread,
Aug 7, 2015, 9:28:15 PM8/7/15
to
Subs don't terminate with a semicolon, but variable
declarations do.

T

unread,
Aug 7, 2015, 9:30:15 PM8/7/15
to
Hi Rainer,

Thank you.

-T

Where you teasing about the Fibonacci number?

T

unread,
Aug 7, 2015, 9:37:01 PM8/7/15
to
Okay. You can do it with "my" variables set up to
reference (point) to the subroutines.

The way I have always seen it before (Pascal, Modula2)
was to just include a sub inside another sub. When you
did that, no one else except the sub it was embedded
in could see it.

No big deal. I just have top be careful what I call my
subs that are called by others subs.

Thank you for helping me with this!

-T


Mart van de Wege

unread,
Aug 8, 2015, 4:14:09 AM8/8/15
to
T <T...@invalid.invalid> writes:

> On 08/04/2015 01:19 AM, Mart van de Wege wrote:
>> T <T...@invalid.invalid> writes:
>>
>>> On 08/03/2015 11:30 PM, Mart van de Wege wrote:
>>>> T <T...@invalid.invalid> writes:
>>>>
>>>>>
>>>>>
>>>>> What does "$fibber->()" mean?
>>>>
>>>> It means 'call the subroutine reference in $fibber and pass it the
>>>> values between ()'.
>>>>
>>>> Mart
>>>>
>>>
>>> I am not following. :-[
>>
>> You can take a reference to a subroutine and assign it to a
>> variable. The way to execute it later is to apply the -> operator to
>> that variable.
>>
>> Try this:
>>
>> use strict;
>> use warnings;
>>
>> my $sub_example = sub {
>> my $arg = shift;
>> print "anonymous sub executing now with argument $arg.\n";
>> }
>
> You forget the semicolon
>
D'oh. That's what you get for not running your own examples.

Jens Thoms Toerring

unread,
Aug 8, 2015, 7:18:58 AM8/8/15
to
T <T...@invalid.invalid> wrote:
> Just out of curiosity, how are you getting away with addressing
> an element in an array with "@"

> print @$arr_ref[ 0 ], "\n";

> Where ever I do it I get the finger shaken at me.

> $ perl -e 'use strict; use warnings; my @A=(11,22,33); print "@A[2]
> \n";'

> Scalar value @A[2] better written as $A[2] at -e line 1.
> 33

There's a difference between '@A[2]' and '@$arr_ref[2]' - the
first one is considered a bit fishy by Perl, but the second
does not give that warning (at least for me).

If you look up the explanation for the warning in 'perldoc perldiag'
you'll find

Scalar value @%s[%s] better written as $%s[%s]
(W syntax) You've used an array slice (indicated by @) to select a
single element of an array. Generally it's better to ask for a
scalar value (indicated by $). The difference is that $foo[&bar]
always behaves like a scalar, both when assigning to it and when
evaluating its argument, while @foo[&bar] behaves like a list when
you assign to it, and provides a list context to its subscript,
which can do weird things if you're expecting only one subscript.

On the other hand, if you were actually hoping to treat the array
element as a list, you need to look into how references work,
because Perl will not magically convert between scalars and lists
for you. See perlref.

BTW, if you want to get that kind of explanation for every
warning just add

use diagnostics;

to ypur scripts and Perl becomes a lot more verbose in these cases.

It's different for '@$arr_ref[2]': here, given that '$arr_ref' is
a reference, the '@' works as the "dereferencing operator", giving
you the underlying array you then can use the '[]' on - there does
not seem to be a possible problem with getting confused with an
array slice (or at least Perl didn't warn me about it;-)

Rainer Weikusat

unread,
Aug 8, 2015, 7:44:32 AM8/8/15
to
The code I posted didn't. It compiles with perl -cw -Mstrict without
errors and prints the first 16 Fibonacci numbers when executed.

T

unread,
Aug 8, 2015, 5:44:36 PM8/8/15
to
On 08/08/2015 01:07 AM, Mart van de Wege wrote:
> T <T...@invalid.invalid> writes:
>
>> On 08/04/2015 01:19 AM, Mart van de Wege wrote:
>>> T <T...@invalid.invalid> writes:
>>>
>>>> On 08/03/2015 11:30 PM, Mart van de Wege wrote:
>>>>> T <T...@invalid.invalid> writes:
>>>>>
>>>>>>
>>>>>>
>>>>>> What does "$fibber->()" mean?
>>>>>
>>>>> It means 'call the subroutine reference in $fibber and pass it the
>>>>> values between ()'.
>>>>>
>>>>> Mart
>>>>>
>>>>
>>>> I am not following. :-[
>>>
>>> You can take a reference to a subroutine and assign it to a
>>> variable. The way to execute it later is to apply the -> operator to
>>> that variable.
>>>
>>> Try this:
>>>
>>> use strict;
>>> use warnings;
>>>
>>> my $sub_example = sub {
>>> my $arg = shift;
>>> print "anonymous sub executing now with argument $arg.\n";
>>> }
>>
>> You forget the semicolon
>>
> D'oh. That's what you get for not running your own examples.
>
>

Hi Mart,

No problem.

I stared and stared at it. I was sure an ending "}" did not
require a ";". I did not realize that I was terminating
the "my", not the "sub". I figured it out by throwing
semicolons everywhere until the complaining stopped.

It was a good learning problem for me to solve. Sometimes it
pays to goof a few thing up! :-)

Thank you for helping me with this,

-T

T

unread,
Aug 8, 2015, 5:46:52 PM8/8/15
to
On 08/08/2015 04:44 AM, Rainer Weikusat wrote:
> T <T...@invalid.invalid> writes:
>> On 08/04/2015 03:00 AM, Rainer Weikusat wrote:
>>> Why don't you run the code instead of wondering about it?
>>
>> I am as I write this. It has syntax errors.

Found a fixed and learned something.

>
> The code I posted didn't. It compiles with perl -cw -Mstrict without
> errors and prints the first 16 Fibonacci numbers when executed.

I was just confused as to were you got your Fibonacci
chain from. And, where did you apply the seed, if
any?



T

unread,
Aug 8, 2015, 5:49:32 PM8/8/15
to
Hi Jens,

"use diagnostics;" is now in my template. :-)

>
> to ypur scripts and Perl becomes a lot more verbose in these cases.
>
> It's different for '@$arr_ref[2]': here, given that '$arr_ref' is
> a reference, the '@' works as the "dereferencing operator", giving
> you the underlying array you then can use the '[]' on - there does
> not seem to be a possible problem with getting confused with an
> array slice (or at least Perl didn't warn me about it;-)
>
> Regards, Jens
>

Thank you for helping me with this!
-T

Mart van de Wege

unread,
Aug 8, 2015, 6:42:07 PM8/8/15
to
T <T...@invalid.invalid> writes:

> On 08/08/2015 01:07 AM, Mart van de Wege wrote:
>> T <T...@invalid.invalid> writes:
>>
>>> On 08/04/2015 01:19 AM, Mart van de Wege wrote:

<snip>

>>>> You can take a reference to a subroutine and assign it to a
>>>> variable. The way to execute it later is to apply the -> operator to
>>>> that variable.
>>>>
>>>> Try this:
>>>>
>>>> use strict;
>>>> use warnings;
>>>>
>>>> my $sub_example = sub {
>>>> my $arg = shift;
>>>> print "anonymous sub executing now with argument $arg.\n";
>>>> }
>>>
>>> You forget the semicolon
>>>
>> D'oh. That's what you get for not running your own examples.
>>
>>
>
> Hi Mart,
>
> No problem.
>
> I stared and stared at it. I was sure an ending "}" did not
> require a ";". I did not realize that I was terminating
> the "my", not the "sub". I figured it out by throwing
> semicolons everywhere until the complaining stopped.

Indeed. Normally a block does not require a terminating ;, however in
this case the expression to be terminated is the assignment, so a
semicolon after the block of the anonymous sub definition is mandatory.

Mart

Rainer Weikusat

unread,
Aug 9, 2015, 6:40:44 AM8/9/15
to
The main subroutine of the code I posted was this:

sub make_fibber
{
my ($v0, $v1);

return sub {
my $next = $v0 + $v1 || 1;

$v0 = $v1;
$v1 = $next;

return $next;
};
}

The important thing to note here is that make_fibber returns a newly
created subroutine which will retain access to the $v0 and $v1 which
existed at the time the subroutine was created and which are going to be
used to hold the last two Fibonacci numbers which are needed in creating
the next one. Initially, they have no value which counts as 0 when used
as a number. I consider this a feature. Outputs are calculated as

my $next = $v0 + $v1 || 1;

This means 'The next Fibonacci number is the sum of $v0 and $v1 unless
this sum is 0. In this case, use 1'. The second case occurs only when
the returned closure is called for the first time.
0 new messages