Re: More idiomatic

Discussion in 'Perl Misc' started by C.DeRykus, Apr 18, 2013.

  1. C.DeRykus

    C.DeRykus Guest

    On Wednesday, April 17, 2013 7:54:31 AM UTC-7, David Harmon wrote:
    > On Wed, 17 Apr 2013 07:37:29 +0100 in comp.lang.perl.misc, Ben
    >
    > Morrow <> wrote,
    >
    > >I think the strategy I might go for here would be to concatenate the

    >
    > >pieces to get a unique key, but not try to pull them out again

    >
    > >afterwards. Instead put the individual pieces in a structure,

    >
    >
    >
    > Yes, I think that is a good answer.



    One possibility to avoid an artificial concatenation
    character and then needing to break it down later:


    my $key = "$fromline$useragent$hascont";
    $statstab{$key} = [
    (${$statstab{$key}}[0] //= $fromline),
    (${$statstab{$key}}[1] //= $useragent),
    (${$statstab{$key}}[2] //= $hascont),
    do{${$statstab{$key}}[3] //= 0; ++${$statstab{$key}}[3]}
    ];

    ....
    for (sort keys %statstab) {
    ($fromline,$useragent,$hascont) = @{$statstab{$_}}[0.2]
    ...


    --
    Charles DeRykus
     
    C.DeRykus, Apr 18, 2013
    #1
    1. Advertising

  2. C.DeRykus

    C.DeRykus Guest

    On Wednesday, April 17, 2013 11:02:51 PM UTC-7, C.DeRykus wrote:
    > On Wednesday, April 17, 2013 7:54:31 AM UTC-7, David Harmon wrote:
    >
    > > On Wed, 17 Apr 2013 07:37:29 +0100 in comp.lang.perl.misc, Ben

    >
    > >

    >
    > > Morrow <> wrote,

    >
    > >

    >
    > > >I think the strategy I might go for here would be to concatenate the

    >
    > >

    >
    > > >pieces to get a unique key, but not try to pull them out again

    >
    > >

    >
    > > >afterwards. Instead put the individual pieces in a structure,

    >
    > >

    >
    > >

    >
    > >

    >
    > > Yes, I think that is a good answer.

    >
    >
    >
    >
    >
    > One possibility to avoid an artificial concatenation
    >
    > character and then needing to break it down later:
    >
    >
    >
    >
    >
    > my $key = "$fromline$useragent$hascont";
    >
    > $statstab{$key} = [
    >
    > (${$statstab{$key}}[0] //= $fromline),
    >
    > (${$statstab{$key}}[1] //= $useragent),
    >
    > (${$statstab{$key}}[2] //= $hascont),
    >
    > do{${$statstab{$key}}[3] //= 0; ++${$statstab{$key}}[3]}
    >
    > ];
    >
    >
    >


    Untested... and I see quickly that this re-creates the
    array each time which isn't terribly efficient, eg, if
    the $statstab key already exists, you could just update
    the count.

    --
    Charles DeRykus
     
    C.DeRykus, Apr 18, 2013
    #2
    1. Advertising

  3. C.DeRykus

    C.DeRykus Guest

    On Wednesday, April 17, 2013 11:18:05 PM UTC-7, C.DeRykus wrote:
    > On Wednesday, April 17, 2013 11:02:51 PM UTC-7, C.DeRykus wrote:
    >
    > > On Wednesday, April 17, 2013 7:54:31 AM UTC-7, David Harmon wrote:

    >
    > >

    >
    > > > On Wed, 17 Apr 2013 07:37:29 +0100 in comp.lang.perl.misc, Ben

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > Morrow <> wrote,

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > >I think the strategy I might go for here would be to concatenate the

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > >pieces to get a unique key, but not try to pull them out again

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > >afterwards. Instead put the individual pieces in a structure,

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > Yes, I think that is a good answer.

    >
    > >

    >
    > >

    >
    > >

    >
    > >

    >
    > >

    >
    > > One possibility to avoid an artificial concatenation

    >
    > >

    >
    > > character and then needing to break it down later:

    >
    > >

    >
    > >

    >
    > >

    >
    > >

    >
    > >

    >
    > > my $key = "$fromline$useragent$hascont";

    >
    > >

    >
    > > $statstab{$key} = [

    >
    > >

    >
    > > (${$statstab{$key}}[0] //= $fromline),

    >
    > >

    >
    > > (${$statstab{$key}}[1] //= $useragent),

    >
    > >

    >
    > > (${$statstab{$key}}[2] //= $hascont),

    >
    > >

    >
    > > do{${$statstab{$key}}[3] //= 0; ++${$statstab{$key}}[3]}

    >
    > >

    >
    > > ];

    >
    > >

    >
    > >

    >
    > >

    >
    >
    >
    > Untested... and I see quickly that this re-creates the
    >
    > array each time which isn't terribly efficient, eg, if
    >
    > the $statstab key already exists, you could just update
    >
    > the count.
    >
    >


    Better ... lightly tested:

    ...
    my $key = "$fromline$useragent$hascont";
    if ( exists $statstab{$key} ) {
    ${$statstab{$key}}[3]++;
    } else {
    $statstab{$key} = [$fromline, $useragent, $hascont,1];
    }
    ....

    --
    Charles DeRykus
     
    C.DeRykus, Apr 18, 2013
    #3
  4. "C.DeRykus" <> wrote:
    >On Wednesday, April 17, 2013 11:18:05 PM UTC-7, C.DeRykus wrote:
    >> On Wednesday, April 17, 2013 11:02:51 PM UTC-7, C.DeRykus wrote:
    >>
    >> > On Wednesday, April 17, 2013 7:54:31 AM UTC-7, David Harmon wrote:

    >>
    >> >

    >>
    >> > > On Wed, 17 Apr 2013 07:37:29 +0100 in comp.lang.perl.misc, Ben

    >>
    >> >

    >>
    >> > >

    >>
    >> >

    >>
    >> > > Morrow <> wrote,

    >>
    >> >

    >>
    >> > >

    >>
    >> >

    >>
    >> > > >I think the strategy I might go for here would be to concatenate the

    >>
    >> >

    >>
    >> > >

    >>
    >> >

    >>
    >> > > >pieces to get a unique key, but not try to pull them out again

    >>
    >> >

    >>
    >> > >

    >>
    >> >

    >>
    >> > > >afterwards. Instead put the individual pieces in a structure,

    [...]

    As if full-quotes aren't bad enough is there any sane reason why you are
    doubling your quotes by inserting an additional empty line after each
    and every quoted line? That is nuts!
    And yet worse: attribute those added lines to the previous poster?

    Would you stop doing that ASAP, please.

    jue
     
    Jürgen Exner, Apr 18, 2013
    #4
  5. C.DeRykus

    Dr.Ruud Guest

    On 2013-04-18 10:07, C.DeRykus wrote:

    > ${$statstab{$key}}[3]++;


    Alternative:

    ++ $statstab{$key}[3];

    --
    Ruud
     
    Dr.Ruud, Apr 18, 2013
    #5
  6. "C.DeRykus" <> writes:

    [...]


    > Better ... lightly tested:
    >
    > ...
    > my $key = "$fromline$useragent$hascont";
    > if ( exists $statstab{$key} ) {
    > ${$statstab{$key}}[3]++;
    > } else {
    > $statstab{$key} = [$fromline, $useragent, $hascont,1];
    > }


    This could be written as

    $statstab{$key} //= [$fromline, $useragent, $hascont];
    ++$statstab{$key}[3];

    (it could also use ||= for compatibility with older Perls since values
    which end up as zero when interpreted as a number shouldn't exist in
    this case). Also, declaring constants for accessing the subfields
    would be a good idea, eg

    use constant COUNT => 3;

    ..
    ..
    ..

    $statstab{$key} //= [$fromline, $useragent, $hascont];
    ++$statstab{$key}[COUNT];
     
    Rainer Weikusat, Apr 18, 2013
    #6
  7. Jürgen Exner <> writes:
    [...]
    > As if full-quotes aren't bad enough is there any sane reason why you are
    > doubling your quotes by inserting an additional empty line after each
    > and every quoted line? That is nuts!
    > And yet worse: attribute those added lines to the previous poster?
    >
    > Would you stop doing that ASAP, please.


    Google Groups does that automatically. Yes, it's stupid.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Apr 18, 2013
    #7
  8. David Harmon <> writes:
    > On Wed, 17 Apr 2013 23:02:51 -0700 (PDT) in comp.lang.perl.misc,
    > "C.DeRykus" <> wrote,
    >>One possibility to avoid an artificial concatenation
    >>character and then needing to break it down later:
    >>
    >>my $key = "$fromline$useragent$hascont";
    >>$statstab{$key} = [
    >> (${$statstab{$key}}[0] //= $fromline),
    >> (${$statstab{$key}}[1] //= $useragent),
    >> (${$statstab{$key}}[2] //= $hascont),

    >
    > Sorry to disagree, but I much prefer Ben's hash with mnemonic keys
    > over this array with numeric indexes that I must track the meaning
    > of by additional effort.


    While this probably doesn't matter much for 'small amounts of code':
    Using declared constants in order to access array slots by name has
    the additional benefit that misspelling a slot name results in a
    compile-time error instead of (when 'use warnings' is in effect) an
    odd runtime warning which happens in some situations aggregated
    together without rhyme or reason, most of which are perfectly normal
    in Perl code, just not 'perfectly normal' in the minds of certain
    people.
     
    Rainer Weikusat, Apr 18, 2013
    #8
  9. On 4/18/2013 10:54 AM, David Harmon wrote:
    > On Wed, 17 Apr 2013 23:02:51 -0700 (PDT) in comp.lang.perl.misc,
    > "C.DeRykus" <> wrote,
    >> One possibility to avoid an artificial concatenation
    >> character and then needing to break it down later:
    >>
    >> my $key = "$fromline$useragent$hascont";
    >> $statstab{$key} = [
    >> (${$statstab{$key}}[0] //= $fromline),
    >> (${$statstab{$key}}[1] //= $useragent),
    >> (${$statstab{$key}}[2] //= $hascont),

    >
    > Sorry to disagree, but I much prefer Ben's hash with mnemonic keys
    > over this array with numeric indexes that I must track the meaning
    > of by additional effort.
    >


    Ok. But this ugly first attempt morphed into a more idiomatic,
    elegant form thanks to some helpful follow-on suggestions:

    use constant COUNT => 3;
    ....
    $statstab{$key} ||= [$fromline, $useragent, $hascont];
    ++$statstab{$key}[COUNT];
    ...

    for (sort keys %statstab) {
    ($fromline,$useragent,$hascont) = @{$statstab{$_}}[0.COUNT-1]
    ...

    Now you have a single mnemonic and you don't have to worry about
    that pesky, ugly concatenation/de-concatenation. Nor do you have
    to sweat pickinng a safe concatenator string. (IMO, the
    multi-dimensional array emulation is ugly, old-school stuff).

    Short, elegant, arguably safer and more idiomatic... at least again
    IMO.

    --
    Charles DeRykus
     
    Charles DeRykus, Apr 18, 2013
    #9
  10. On 4/18/2013 10:28 AM, Keith Thompson wrote:
    > Jürgen Exner <> writes:
    > [...]
    >> As if full-quotes aren't bad enough is there any sane reason why you are
    >> doubling your quotes by inserting an additional empty line after each
    >> and every quoted line? That is nuts!
    >> And yet worse: attribute those added lines to the previous poster?
    >>
    >> Would you stop doing that ASAP, please.

    >
    > Google Groups does that automatically. Yes, it's stupid.
    >


    Evidently, a new GG feature.

    But I'm atoning for my sins by reverting to Thunderbird.

    --
    Charles DeRykus
     
    Charles DeRykus, Apr 18, 2013
    #10
  11. On 4/18/2013 1:25 PM, Charles DeRykus wrote:
    > On 4/18/2013 10:54 AM, David Harmon wrote:
    >> On Wed, 17 Apr 2013 23:02:51 -0700 (PDT) in comp.lang.perl.misc,
    >> "C.DeRykus" <> wrote,
    >>> One possibility to avoid an artificial concatenation
    >>> character and then needing to break it down later:
    >>>
    >>> my $key = "$fromline$useragent$hascont";
    >>> $statstab{$key} = [
    >>> (${$statstab{$key}}[0] //= $fromline),
    >>> (${$statstab{$key}}[1] //= $useragent),
    >>> (${$statstab{$key}}[2] //= $hascont),

    >>
    >> Sorry to disagree, but I much prefer Ben's hash with mnemonic keys
    >> over this array with numeric indexes that I must track the meaning
    >> of by additional effort.
    >>

    >
    > Ok. But this ugly first attempt morphed into a more idiomatic,
    > elegant form thanks to some helpful follow-on suggestions:
    >
    > use constant COUNT => 3;
    > ...
    > $statstab{$key} ||= [$fromline, $useragent, $hascont];
    > ++$statstab{$key}[COUNT];
    > ...
    >
    > for (sort keys %statstab) {
    > ($fromline,$useragent,$hascont) = @{$statstab{$_}}[0.COUNT-1]
    > ...
    >
    > Now you have a single mnemonic and you don't have to worry about
    > that pesky, ugly concatenation/de-concatenation. Nor do you have
    > to sweat pickinng a safe concatenator string. (IMO, the
    > multi-dimensional array emulation is ugly, old-school stuff).
    >
    > Short, elegant, arguably safer and more idiomatic... at least again
    > IMO.



    Per suggestion, you could use a concatenation separator to completely
    bullet-proof:

    # my $key = "$fromline$useragent$hascont";
    my $key = join($;,$fromline, $useragent, $hascont); # <-- safer

    --
    Charles DeRykus
     
    Charles DeRykus, Apr 19, 2013
    #11
    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. Zed A. Shaw
    Replies:
    2
    Views:
    109
    Zed A. Shaw
    Apr 23, 2005
  2. Charles Calvert
    Replies:
    33
    Views:
    370
    w_a_x_man
    Oct 22, 2010
  3. Alan Mead
    Replies:
    4
    Views:
    145
    Alan Mead
    Feb 12, 2005
  4. J. Gleixner

    Re: More idiomatic

    J. Gleixner, Apr 15, 2013, in forum: Perl Misc
    Replies:
    11
    Views:
    279
    Rainer Weikusat
    Apr 16, 2013
  5. Rainer Weikusat

    Re: More idiomatic

    Rainer Weikusat, Apr 15, 2013, in forum: Perl Misc
    Replies:
    1
    Views:
    172
    Rainer Weikusat
    Apr 15, 2013
Loading...

Share This Page