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.