Combine hash declaration/assignment into single statement?

Discussion in 'Perl Misc' started by usenet@DavidFilmer.com, Feb 28, 2006.

  1. Guest

    It is often possible to declare and assign a variable in a single
    statement, such as:
    my $foo = 'bar';
    or
    my @foo = qw{bar baz};

    Is it possible to do this in a single statement (under strict):

    my %character_value;
    @character_value{'a'..'z'} = (1..26);


    Thanks!

    --
    http://DavidFilmer.com
    , Feb 28, 2006
    #1
    1. Advertising

  2. Uri Guttman Guest

    >>>>> "u" == usenet <> writes:

    u> It is often possible to declare and assign a variable in a single
    u> statement, such as:
    u> my $foo = 'bar';
    u> or
    u> my @foo = qw{bar baz};

    u> Is it possible to do this in a single statement (under strict):

    u> my %character_value;
    u> @character_value{'a'..'z'} = (1..26);

    not with that data in one statment. but there are many variations which
    can be used.

    first, you may already have the keys in an array for various reasons
    (ordering, read from somewhere else, etc.). then you can use map to
    assign integer values:

    my @chars = ( 'a' .. 'z' ) ;
    my %foo = map { $chars[$_ - 1] => $_ } 1 .. @chars ;

    if you don't mind destroying @chars (say a copy is used) this works:

    my %foo = map { shift @chars => $_ } 1 .. @chars ;

    that can be used to merge two arrays if either one can be destroyed:

    my %foo = map { shift @keys => $_ } @values ;
    my %foo = map { $_ => shift @values } @keys ;

    or if you just wanted the keys to exist (for checking if a string is in
    a set):

    my %foo = map { $_ => undef } @chars ;

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Feb 28, 2006
    #2
    1. Advertising

  3. Rick Scott Guest

    ( uttered:)
    > It is often possible to declare and assign a variable in a single
    > statement, such as:
    > my $foo = 'bar';
    > or
    > my @foo = qw{bar baz};
    >
    > Is it possible to do this in a single statement (under strict):
    >
    > my %character_value;
    > @character_value{'a'..'z'} = (1..26);


    My first thought was to do this:

    #!/usr/bin/perl

    use warnings;
    use strict;
    use List::MoreUtils qw(zip);

    my %character_value = zip('a'..'z', 1..26);

    But as it turns out, there is a subtle distinction between lists and
    arrays of which I was not previously aware, and List::MoreUtils::zip
    needs arrays:

    Type of arg 1 to List::MoreUtils::mesh must be array (not null
    operation) at foo.pl line 14, near "26)"
    Type of arg 2 to List::MoreUtils::mesh must be array (not null
    operation) at foo.pl line 14, near "26)"


    It's not a single statement, but (in addition to any of Uri's
    excellent suggestions) you can still do this:

    #!/usr/bin/perl

    use warnings;
    use strict;
    use List::MoreUtils qw(zip);

    my @keys = 'a'..'z';
    my @values = 1..26;

    my %character_value = zip(@keys, @values);




    Rick
    --
    key CF8F8A75 / print C5C1 F87D 5056 D2C0 D5CE D58F 970F 04D1 CF8F 8A75
    Aren't your machines getting faster much more quickly than your
    programmers are getting smarter?
    :peter Coffee
    Rick Scott, Feb 28, 2006
    #3
  4. Sisyphus Guest

    "Rick Scott" <> wrote in message
    news:1141164252.bcde7D.14245@shadowspar...
    > ( uttered:)
    > > It is often possible to declare and assign a variable in a single
    > > statement, such as:
    > > my $foo = 'bar';
    > > or
    > > my @foo = qw{bar baz};
    > >
    > > Is it possible to do this in a single statement (under strict):
    > >
    > > my %character_value;
    > > @character_value{'a'..'z'} = (1..26);

    >
    > My first thought was to do this:
    >
    > #!/usr/bin/perl
    >
    > use warnings;
    > use strict;
    > use List::MoreUtils qw(zip);
    >
    > my %character_value = zip('a'..'z', 1..26);
    >
    > But as it turns out, there is a subtle distinction between lists and
    > arrays of which I was not previously aware, and List::MoreUtils::zip
    > needs arrays:
    >


    I think it's the anonymity that trips it up. If you provide anonymous arrays
    as the arguments:

    my %character_value = zip(('a' .. 'z'), (1 .. 26));

    then you still get the same error.

    Cheers,
    Rob
    Sisyphus, Feb 28, 2006
    #4
  5. Uri Guttman Guest

    >>>>> "S" == Sisyphus <> writes:

    >> my %character_value = zip('a'..'z', 1..26);
    >>
    >> But as it turns out, there is a subtle distinction between lists and
    >> arrays of which I was not previously aware, and List::MoreUtils::zip
    >> needs arrays:
    >>


    S> I think it's the anonymity that trips it up. If you provide anonymous arrays
    S> as the arguments:

    S> my %character_value = zip(('a' .. 'z'), (1 .. 26));

    S> then you still get the same error.

    that code is the exact same thing as the above code. in both cases zip
    sees a single list of values. your extra parens did nothing and they
    aren't anon arrays. you need [] for that. my guess (easily verified by
    the docs or code) is that zip has a prototype looking for @ (possibly
    \@). lists can only be passed to a sub as the last argument anyhow. you
    can never pass 2 lists to a sub.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Mar 1, 2006
    #5
  6. Lukas Mai Guest

    schrob:
    >
    > Is it possible to do this in a single statement (under strict):
    >
    > my %character_value;
    > @character_value{'a'..'z'} = (1..26);


    Not really, but there's

    my %character_value = map +($_ => ord($_) - ord('a') + 1), 'a' .. 'z';

    HTH, Lukas
    Lukas Mai, Mar 1, 2006
    #6
  7. Sisyphus Guest

    "Uri Guttman" <> wrote in message
    >
    > S> I think it's the anonymity that trips it up. If you provide anonymous

    arrays
    > S> as the arguments:
    >
    > S> my %character_value = zip(('a' .. 'z'), (1 .. 26));
    >
    > S> then you still get the same error.
    >

    ..
    ..
    >your extra parens did nothing and they
    > aren't anon arrays. you need [] for that.


    Oh ... I've always thought that the square brackets created a "reference to
    a list" - and that a "reference to a list" and an "anonymous array" are
    different things. (You can see from the above what I thought an anonymous
    array was.) Thanks for the correction.

    Cheers,
    Rob
    Sisyphus, Mar 1, 2006
    #7
  8. Rick Scott Guest

    (Uri Guttman <> uttered:)
    > >>>>> "S" == Sisyphus <> writes:

    >
    > S> I think it's the anonymity that trips it up. If you provide
    > S> anonymous arrays as the arguments:
    >
    > S> my %character_value = zip(('a' .. 'z'), (1 .. 26));
    >
    > S> then you still get the same error.
    >
    > that code is the exact same thing as the above code. in both cases
    > zip sees a single list of values. your extra parens did nothing
    > and they aren't anon arrays. you need [] for that. my guess
    > (easily verified by the docs or code) is that zip has a prototype
    > looking for @ (possibly \@).


    Exactly right:

    # List::MoreUtils.pm -- zip is aliased to mesh
    sub mesh
    (\@\@;\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@) {
    my $max = -1;
    $max < $#$_ && ($max = $#$_) for @_;

    map { my $ix = $_; map $_->[$ix], @_; } 0..$max;
    }

    Funny; for some reason I'd been labouring under the mistaken
    impression that function prototypes were practically ornamental.
    Obviously time for more study.




    Rick
    --
    key CF8F8A75 / print C5C1 F87D 5056 D2C0 D5CE D58F 970F 04D1 CF8F 8A75
    A masterful retreat is itself a victory.
    :N. V. Peale
    Rick Scott, Mar 2, 2006
    #8
  9. Samwyse Guest

    Lukas Mai wrote:
    > schrob:
    >
    >>Is it possible to do this in a single statement (under strict):
    >>
    >> my %character_value;
    >> @character_value{'a'..'z'} = (1..26);

    >
    >
    > Not really, but there's
    >
    > my %character_value = map +($_ => ord($_) - ord('a') + 1), 'a' .. 'z';


    Just to be pedantic, all of this only works under character encodings
    (like ASCII) where 'a'..'z' are contigious values; under EBCDIC, for
    instance, 'a'..'z' is a list of 40 values, some of which are not
    alphabetic. The expression (grep/\w/,'a'..'z') will get you back down
    to 26 values.
    Samwyse, Mar 2, 2006
    #9
  10. Paul Lalli Guest

    Sisyphus wrote:
    > Oh ... I've always thought that the square brackets created a "reference to
    > a list" - and that a "reference to a list" and an "anonymous array" are
    > different things. (You can see from the above what I thought an anonymous
    > array was.) Thanks for the correction.


    There's no such thing as a reference to a list. [1]
    You can have a reference to an array.
    That array can be named, or it can be anonymous.

    Once you have your reference, you can dereference it. Thus giving you
    an array.

    my @array = (1..5); # a named array;
    my $a_ref = \@array; # a reference to a named array.
    my $a_ref2 = [ 1.. 5 ]; # a reference to an anonymous array.

    print @$a_ref; #the same array as the named array @array.
    print @$a_ref2; #the anonymous array referenced by $a_ref2

    @$a_ref2 is an anonymous array, because it does not have a name. It
    has only a reference. The only way of using it is by dereferencing its
    reference.

    Paul Lalli

    [1]. The syntax that you might expect to create such a thing:
    \($foo, $bar, $baz)
    actually creates a list of references, not a reference to a list. That
    is, it creates:
    (\$foo, \$bar, \$baz);
    (in list context, anyway. In scalar context, it creates each
    reference, but returns only the last one).
    Paul Lalli, Mar 2, 2006
    #10
  11. Anno Siegel Guest

    Rick Scott <> wrote in comp.lang.perl.misc:
    > ( uttered:)
    > > It is often possible to declare and assign a variable in a single
    > > statement, such as:
    > > my $foo = 'bar';
    > > or
    > > my @foo = qw{bar baz};
    > >
    > > Is it possible to do this in a single statement (under strict):
    > >
    > > my %character_value;
    > > @character_value{'a'..'z'} = (1..26);

    >
    > My first thought was to do this:
    >
    > #!/usr/bin/perl
    >
    > use warnings;
    > use strict;
    > use List::MoreUtils qw(zip);
    >
    > my %character_value = zip('a'..'z', 1..26);
    >
    > But as it turns out, there is a subtle distinction between lists and
    > arrays of which I was not previously aware, and List::MoreUtils::zip
    > needs arrays:


    Then give it arrays:

    my %character_value = zip @{ [ 'a' .. 'z'] }, @{ [ 1 .. 26] };

    or, overriding the prototype:

    my %character_value = &zip( [ 'a' .. 'z'], [ 1 .. 26]);

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Mar 3, 2006
    #11
  12. DJ Stunks Guest

    Anno Siegel wrote:
    > or, overriding the prototype:
    >
    > my %character_value = &zip( [ 'a' .. 'z'], [ 1 .. 26]);


    :) very nice.

    I wasn't totally clear on the role of & previously...

    -jp
    DJ Stunks, Mar 3, 2006
    #12
  13. Rick Scott Guest

    (Anno Siegel <-berlin.de> uttered:)
    > Rick Scott <> wrote:
    > > my %character_value = zip('a'..'z', 1..26);
    > >
    > > But as it turns out, there is a subtle distinction between lists
    > > and arrays of which I was not previously aware, and
    > > List::MoreUtils::zip needs arrays ...

    >
    > Then give it arrays:
    >
    > my %character_value = zip @{ [ 'a' .. 'z'] }, @{ [ 1 .. 26] };
    >
    > or, overriding the prototype:
    >
    > my %character_value = &zip( [ 'a' .. 'z'], [ 1 .. 26]);
    >


    That's the syntax I was looking for but couldn't seem to figure out.
    Thanks Anno.




    Rick
    --
    key CF8F8A75 / print C5C1 F87D 5056 D2C0 D5CE D58F 970F 04D1 CF8F 8A75
    When wise men disapprove, that's bad;
    when fools applaud, that's worse.
    :Spanish proverb
    Rick Scott, Mar 3, 2006
    #13
  14. Uri Guttman Guest

    >>>>> "DS" == DJ Stunks <> writes:

    DS> Anno Siegel wrote:
    >> or, overriding the prototype:
    >>
    >> my %character_value = &zip( [ 'a' .. 'z'], [ 1 .. 26]);


    DS> :) very nice.

    DS> I wasn't totally clear on the role of & previously...

    i was going to skip this but now that you decided it was a good idea, i
    have to comment. & has several uses and almost all are poor to bad. the
    simplest and safest is that you can call subs without () or predeclaring
    them (via use subs or sub foo). another thing it does which is very
    nasty is to call subs like &foo ;. that passes the currently @_ to the
    called sub so this can lead to nasty bugs where you don't deal properly
    with @_. the other thing it does is shut off prototypes as anno
    shows. but if there was a reason for prototypes (in this case taking two
    array args) then defeating that can be nasty. it smacks of breaking
    encapsulation as well. i find it troublesome that a prototype of \@
    won't allow an array ref to be passed instead of a real array. well p6
    will handle that correctly.

    also i tried to install List::MoreUtils to play with zip but when it
    started to install XML and SAX stuff i killed it. $DEITY knows what
    other crap tha module depends on. i would hope zip() doesn't need that
    but then why bundle it with stuff that uses so many other modules? bah!

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Mar 3, 2006
    #14
  15. Dr.Ruud Guest

    Uri Guttman schreef:

    > i was going to skip this but now that you decided it was a good idea,
    > i have to comment. & has several uses and almost all are poor to bad.
    > the simplest and safest is that you can call subs without () or
    > predeclaring them (via use subs or sub foo).


    Starting sentences without a capital letter, makes your postings less
    readable.

    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, Mar 3, 2006
    #15
  16. DJ Stunks Guest

    Uri Guttman wrote:
    > >>>>> "DS" == DJ Stunks <> writes:

    >
    > DS> Anno Siegel wrote:
    > >> or, overriding the prototype:
    > >>
    > >> my %character_value = &zip( [ 'a' .. 'z'], [ 1 .. 26]);

    >
    > DS> :) very nice.
    >
    > DS> I wasn't totally clear on the role of & previously...
    >
    > i was going to skip this but now that you decided it was a good idea, i
    > have to comment. & has several uses and almost all are poor to bad. the
    > simplest and safest is that you can call subs without () or predeclaring
    > them (via use subs or sub foo). another thing it does which is very
    > nasty is to call subs like &foo ;. that passes the currently @_ to the
    > called sub so this can lead to nasty bugs where you don't deal properly
    > with @_. the other thing it does is shut off prototypes as anno
    > shows. but if there was a reason for prototypes (in this case taking two
    > array args) then defeating that can be nasty. it smacks of breaking
    > encapsulation as well. i find it troublesome that a prototype of \@
    > won't allow an array ref to be passed instead of a real array. well p6
    > will handle that correctly.


    Thanks for those explanations.


    > also i tried to install List::MoreUtils to play with zip but when it
    > started to install XML and SAX stuff i killed it. $DEITY knows what
    > other crap tha module depends on. i would hope zip() doesn't need that
    > but then why bundle it with stuff that uses so many other modules? bah!


    Um, I'm not sure what was going on there, but from the README:

    List-MoreUtils version 0.18
    ===========================

    <snip>

    DEPENDENCIES

    This module requires these other modules and libraries:

    No modules, but a C compiler would be nice
    (although not strictly required)

    You might want to try again? it's a very handy module.

    -jp
    DJ Stunks, Mar 3, 2006
    #16
  17. Uri Guttman Guest

    >>>>> "DS" == DJ Stunks <> writes:

    DS> Uri Guttman wrote:

    >> also i tried to install List::MoreUtils to play with zip but when it
    >> started to install XML and SAX stuff i killed it. $DEITY knows what
    >> other crap tha module depends on. i would hope zip() doesn't need that
    >> but then why bundle it with stuff that uses so many other modules? bah!


    DS> Um, I'm not sure what was going on there, but from the README:

    DS> List-MoreUtils version 0.18
    DS> ===========================

    DS> <snip>

    DS> DEPENDENCIES

    DS> This module requires these other modules and libraries:

    DS> No modules, but a C compiler would be nice
    DS> (although not strictly required)

    then my cpan.pm is smoking crack. i should probably upgrade it too.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Mar 3, 2006
    #17
  18. Rick Scott Guest

    (Uri Guttman <> uttered:)
    > >>>>> "DS" == DJ Stunks <> writes:

    >
    > DS> Anno Siegel wrote:
    > >> or, overriding the prototype:
    > >>
    > >> my %character_value = &zip( [ 'a' .. 'z'], [ 1 .. 26]);

    >
    > DS> :) very nice.
    > DS> I wasn't totally clear on the role of & previously...
    >
    > i was going to skip this but now that you decided it was a good
    > idea, i have to comment. & has several uses and almost all are
    > poor to bad. ...
    > the other thing it does is shut off prototypes as anno shows. but
    > if there was a reason for prototypes (in this case taking two
    > array args) then defeating that can be nasty.


    Heh. I discovered this when I tried using & to skip zip's prototype:

    shadow> cat zip.pl

    #!/usr/bin/perl

    use warnings;
    use strict;
    use List::MoreUtils qw(zip);

    my %character_value = &zip ('a'..'z', 1..26);

    shadow> ./zip.pl
    Segmentation fault

    Can't say I've ever managed to do that with Perl before.




    Rick
    --
    key CF8F8A75 / print C5C1 F87D 5056 D2C0 D5CE D58F 970F 04D1 CF8F 8A75
    The most personable person over there is the mailer-daemon.
    :Anonymous Coward
    Rick Scott, Mar 3, 2006
    #18
  19. Anno Siegel Guest

    Rick Scott <> wrote in comp.lang.perl.misc:
    > (Uri Guttman <> uttered:)
    > > >>>>> "DS" == DJ Stunks <> writes:

    > >
    > > DS> Anno Siegel wrote:
    > > >> or, overriding the prototype:
    > > >>
    > > >> my %character_value = &zip( [ 'a' .. 'z'], [ 1 .. 26]);

    > >
    > > DS> :) very nice.
    > > DS> I wasn't totally clear on the role of & previously...
    > >
    > > i was going to skip this but now that you decided it was a good
    > > idea, i have to comment. & has several uses and almost all are
    > > poor to bad. ...
    > > the other thing it does is shut off prototypes as anno shows. but
    > > if there was a reason for prototypes (in this case taking two
    > > array args) then defeating that can be nasty.

    >
    > Heh. I discovered this when I tried using & to skip zip's prototype:
    >
    > shadow> cat zip.pl
    >
    > #!/usr/bin/perl
    >
    > use warnings;
    > use strict;
    > use List::MoreUtils qw(zip);
    >
    > my %character_value = &zip ('a'..'z', 1..26);
    >
    > shadow> ./zip.pl
    > Segmentation fault
    >
    > Can't say I've ever managed to do that with Perl before.


    Ah, it looks like zip() believes in its prototype and doesn't check
    its arguments. It's easy to segfault that way.

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Mar 3, 2006
    #19
  20. Also sprach Uri Guttman:

    >>>>>> "DS" == DJ Stunks <> writes:

    >
    > DS> Anno Siegel wrote:
    > >> or, overriding the prototype:
    > >>
    > >> my %character_value = &zip( [ 'a' .. 'z'], [ 1 .. 26]);

    >
    > DS> :) very nice.
    >
    > DS> I wasn't totally clear on the role of & previously...


    [...]

    > also i tried to install List::MoreUtils to play with zip but when it
    > started to install XML and SAX stuff i killed it. $DEITY knows what
    > other crap tha module depends on. i would hope zip() doesn't need that
    > but then why bundle it with stuff that uses so many other modules? bah!


    'scuse me? List::MoreUtils has no dependencies whatsoever:

    WriteMakefile(
    NAME => 'List::MoreUtils',
    VERSION_FROM => 'lib/List/MoreUtils.pm',
    PREREQ_PM => {},
    ($] >= 5.005 ?
    (ABSTRACT_FROM => 'lib/List/MoreUtils.pm',
    AUTHOR => 'Tassilo von Parseval <>') : ()),
    DEFINE => '-DPERL_EXT', # otherwise 'cxinc' isn't defined
    CONFIGURE => \&init,
    clean => { FILES => 'test.c' }
    );

    and I took great effort that both the XS- and the Perl-implementation of
    its functions work on anything between 5.005_04 and 5.9.4.

    Check your CPAN setup. It's borked. :)

    Tassilo
    --
    use bigint;
    $n=71423350343770280161397026330337371139054411854220053437565440;
    $m=-8,;;$_=$n&(0xff)<<$m,,$_>>=$m,,print+chr,,while(($m+=8)<=200);
    Tassilo v. Parseval, Mar 5, 2006
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Evertjan.
    Replies:
    2
    Views:
    175
    Techy
    Nov 23, 2003
  2. rp
    Replies:
    1
    Views:
    499
    red floyd
    Nov 10, 2011
  3. Squeamizh
    Replies:
    2
    Views:
    118
    Robert Klemme
    Aug 7, 2006
  4. Clint Olsen
    Replies:
    2
    Views:
    149
    Clint Olsen
    Jun 29, 2004
  5. bernd
    Replies:
    0
    Views:
    618
    bernd
    Apr 24, 2012
Loading...

Share This Page