[aklug] Re: slightly OT: Perl Net::LDAP

From: James <marblemunkey@gmail.com>
Date: Tue May 24 2016 - 13:43:11 AKDT

Todd,

What you are seeing is a combination of factors:

1) First ["a" => "b"] is valid because it is syntactically the same as
["a", "b"] (with one minor caveat).

http://perldoc.perl.org/perlop.html#Comma-Operator
"The => operator (sometimes pronounced "fat comma") is a synonym for the
comma except that it causes a word on its left to be interpreted as a
string if it begins with a letter or underscore and is composed only of
letters, digits and underscores. [...] Otherwise, the => operator behaves
exactly as the comma operator or list argument separator, according to
context."

2) Subroutines and functions in perl are passed a _list_ of scalars, not an
array or hash.

http://perldoc.perl.org/perlsub.html#DESCRIPTION
"all functions are passed as parameters one single flat list of scalars,
and all functions likewise return to their caller one single flat list of
scalars. Any arrays or hashes in these call and return lists will collapse,
losing their identities--but you may always use pass-by-reference instead
to avoid this."

3) Lists are completely flattened, including sub hashes or arrays. ["a",
"b"] in list context is identical to {"a" => "b"}

http://perldoc.perl.org/perldata.html#List-value-constructors
"when a LIST is evaluated, each element of the list is evaluated in list
context, and the resulting list value is interpolated into LIST just as if
each individual element were a member of LIST. Thus arrays and hashes lose
their identity in a LIST--the list (@foo,@bar,&SomeSub,%glarch) contains
all the elements of @foo followed by all the elements of @bar, followed by
all the elements returned by the subroutine named SomeSub called in list
context, followed by the key/value pairs of %glarch."

I hope this helps clear things up for you.

- James Gibson

On Tue, May 24, 2016 at 4:58 PM, Todor Fassl <fassl.tod@gmail.com> wrote:

> First, I apologize to Royce for calling him "dude".
>
> But David, my question does not imply that I am not very familiar with the
> basics of using function calls within perl. Quite the contrary. I am
> asking about an anonymous array reference within an anonymous hash
> reference in a parameter in a function call in a perl module.
>
> The second parameter to the Net::LDAP function is a hash reference. One of
> the keys for that hash can be "attrs". This allows you to specify the
> attributes you want to add. In the examples in the documentation on the
> CSPAN web site, it shows that key being set to an anonymous array reference
> -- not a *hash* reference. Yet, the example uses hash syntax.
>
> I don't know how to put it more clearly unless you look at the
> documentation itself. Here's a segment of the example:
>
> --- begin quote ---
> $result = $ldap->add( 'cn=Barbara Jensen, o=University of Michigan,c=US',
> attrs => [
> 'cn' => ['Barbara Jensen', 'Barbs Jensen'],
> 'sn' => 'Jensen',
> 'mail' => 'b.jensen@umich.edu',
> 'objectclass' => ['top', 'person',
> 'organizationalPerson',
> 'inetOrgPerson' ],
> ]
> );
> --- end quote ---
>
> Here the key "attrs" is set to an anonymous array reference (not a hash
> reference) and then it looks like they try to use the strings 'cn', 'sn',
> 'mail', and 'objectclass' as keys. From the code example that I put into my
> second message, it looks like what that code would do is to set the key
> "attrs" to a reference to an array with 8 elements, not a hash with 4
> key/value pairs.
>
> I am asking if anyone can explain that.
>
> I'd chalk it up to just a typo in the documentation except I've found
> several other tutorials with the same syntax. Also, the replace and delete
> functions are similarly confusing.
>
> Essentially, the question boils down to what sense does this make:"['cn'
> => 'Todor Fassl']"
>
> What that creates is a reference to an array with 2 elements -- not a
> reference to a hash with one key/value pair. Try this:
>
> $ perl -e 'print ref(["a" => "b"]) . "\n";'
>
> That displays "array". So even though you apparently set the key/value
> pair "a" => "b" within your anonymous array reference, perldoes not create
> a key/value pair. It can't because it's not a hash reference, it's an array
> reference.
>
> I've just asked the same question like 17 different ways. I don't think I
> can make it any clearer.
>
>
> On 05/24/2016 01:47 PM, David M. Syzdek wrote:
>
>> Todor,
>>
>> I agree, with Royce. Talking down to someone who is attempting to help
>> you
>> is unprofessional and to Royce's defense based upon your question is does
>> appear that you are not very familiar with some of the basics of using
>> function calls within perl modules.
>>
>> Often the first few parameters to a module's function are set parameters
>> which are required, but may accept additional parameters which are
>> optional
>> or more complex than simple scalars. So the LDAP example is doing
>> something similar to the following:
>>
>> Here is my script to illustrate:
>>
>> syzdek@sojourner$ cat test.pl
>> #!/usr/bin/perl -Tw
>> use Data::Dumper;
>> sub mock_up_add($%)
>> {
>> my $dn = shift;
>> my $param = {@_};
>> printf("dn: %s\n", $dn);
>> printf("%s\n", Dumper ($param));
>> }
>>
>> mock_up_add( "cn=Barbara Jensen, o=University of Michigan, c=US",
>> attrs => [
>> 'cn' => ['Barbara Jensen', 'Barbs Jensen'],
>> 'sn' => 'Jensen',
>> 'mail' => 'b.jensen@umich.edu',
>> 'objectclass' => ['top', 'person',
>> 'organizationalPerson',
>> 'inetOrgPerson' ],
>> ]
>> );
>> # end of script
>> syzdek@sojourner$ ./test.pl
>> dn: cn=Barbara Jensen, o=University of Michigan, c=US
>> $VAR1 = {
>> 'attrs' => [
>> 'cn',
>> [
>> 'Barbara Jensen',
>> 'Barbs Jensen'
>> ],
>> 'sn',
>> 'Jensen',
>> 'mail',
>> 'b.jensen@umich.edu',
>> 'objectclass',
>> [
>> 'top',
>> 'person',
>> 'organizationalPerson',
>> 'inetOrgPerson'
>> ]
>> ]
>> };
>> syzdek@sojourner$
>>
>>
>> Additionally, perl modules are often implemented as blessed objects so
>> there would be an additional shift statement for the module itself:
>>
>> sub mock_up_add($%)
>> {
>> my $self = shift;
>> my $dn = shift;
>> my $param = {@_};
>> ...
>>
>>
>>
>> --David M. Syzdek
>>
>> On Tue, May 24, 2016 at 7:45 AM, Royce Williams <royce@tycho.org> wrote:
>>
>> On Tue, May 24, 2016 at 7:37 AM, Todor Fassl <fassl.tod@gmail.com> wrote:
>>>
>>>>
>>>> On 05/20/2016 01:10 PM, Royce Williams wrote:
>>>>
>>>>>
>>>>> On Fri, May 20, 2016 at 9:49 AM, Todor Fassl <fassl.tod@gmail.com>
>>>>>
>>>> wrote:
>>>
>>>>
>>>>>> Essentially, my question is, in perl, what is the difference between
>>>>>> saying:
>>>>>>
>>>>>> $array = ['one' => 1, 'two' => 2];
>>>>>>
>>>>>> and
>>>>>>
>>>>>> $array = {'one' => 1, 'two' => 2};
>>>>>>
>>>>>> I am trying to write an ldap add function in perl. Something in the
>>>>>> documentation puzzles me:
>>>>>> http://search.cpan.org/~gbarr/perl-ldap-0.33/lib/Net/LDAP.pod
>>>>>>
>>>>>> That page shows the second parameter to the add function being a
>>>>>>
>>>>> anonymous
>>>
>>>> array ref created by using brackets, '[ ... ]'.
>>>>>>
>>>>>> But then it appears to use string keys. Doesn't that make it a hash or
>>>>>>
>>>>> an
>>>
>>>> associative array? Therefore, shouldn't it be instantiated with
>>>>>>
>>>>> braces, "{
>>>
>>>> ... }"?
>>>>>>
>>>>>> --
>>>>>> Tod
>>>>>>
>>>>>
>>>>>
>>>>> Braces mean a hash reference.
>>>>>
>>>>> http://stackoverflow.com/a/11839874
>>>>>
>>>>
>>>>
>>>> Dude, isn't it obvious from my question that I know that braces mean a
>>>>
>>> hash reference?
>>>
>>> No. Your original message began with what appeared to be a summary of
>>> your question that seemed to indicate that you did not. I deal with
>>> high volumes of email, and I answered as best as I could with the
>>> information that I had absorbed -- admittedly, by reading too quickly,
>>> but nevertheless in good faith.
>>>
>>> Also, please drop the "dude, isn't it obvious". We try to be more
>>> polite than this in this forum. It's not the way to treat people who
>>> are trying to help you.
>>>
>>> My question is how can the Net::LDAP module use brackets to instantiate
>>>>
>>> a normal array reference and then, apparently, use it as a hash
>>> reference?
>>> I wrote some code to check the validity of my question:
>>>
>>>>
>>>> #!/usr/bin/perl
>>>> use Data::Dumper;
>>>> $junk = {'apple' => 1, 'banana' => 6, 'cherry' => 99};
>>>> print "TYPE=" . ref($junk) . "\n" . Dumper ($junk);
>>>>
>>>> As expected, this gives the following output:
>>>>
>>>> TYPE=HASH
>>>> $VAR1 = {
>>>> 'banana' => 6,
>>>> 'cherry' => 99,
>>>> 'apple' => 1
>>>> };
>>>>
>>>> So far so good. Same code except the braces for the hash reference are
>>>>
>>> changed to brackets:
>>>
>>>>
>>>> #!/usr/bin/perl
>>>> use Data::Dumper;
>>>> $junk = ['apple' => 1, 'banana' => 6, 'cherry' => 99];
>>>> print "TYPE=" . ref($junk) . "\n" . Dumper ($junk);
>>>>
>>>> This displays the following:
>>>>
>>>> TYPE=ARRAY
>>>> $VAR1 = [
>>>> 'apple',
>>>> 1,
>>>> 'banana',
>>>> 6,
>>>> 'cherry',
>>>> 99
>>>> ];
>>>>
>>>> I suspect that in perl, if you treat a normal array reference as a hash
>>>>
>>> reference, it just deals with it. But that seems really sloppy. I can't
>>> be
>>> messing around with my ldap database.
>>>
>>>
>>> I don't have the combo of cycles and competence to delve into this one
>>> -- maybe someone else can field it.
>>>
>>> Royce
>>> ---------
>>> To unsubscribe, send email to <aklug-request@aklug.org>
>>> with 'unsubscribe' in the message body.
>>>
>>>
>>>
>>
>>
> --
> Todd
>
> ---------
> To unsubscribe, send email to <aklug-request@aklug.org>
> with 'unsubscribe' in the message body.
>
>

---------
To unsubscribe, send email to <aklug-request@aklug.org>
with 'unsubscribe' in the message body.
Received on Tue May 24 13:43:36 2016

This archive was generated by hypermail 2.1.8 : Tue May 24 2016 - 13:43:36 AKDT