Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Given;
$dialogLB is a scrolled list box
the method curselection returns a list of selected index's.
the problem;
$what = $choices[$dialogLB->curselection];
Used to work in Perl 5.8.0 (ActiveState, Windows) In 5.8.4 it no longer works, complaning of using an array ref as an index value. My solution;
@index = $dialogLB->curselection; $what = $choices[@index];
is unexceptable due to lazyness.
My question to the Monestary is whats going on? How come this no longer works?

20041001 Edit by Steve_p: Changed title from '5.8.0 != 5.8.4'

Replies are listed 'Best First'.
Re: Tk warning using curselection() with ActiveState 5.8.4
by graff (Chancellor) on Sep 30, 2004 at 12:03 UTC
    When you say that this "worked":
    $what = $choices[$dialogLB->curselection];
    I'd have to ask: in what sense did it "work"? That is, when you don't get the error in 5.8.0, what exactly do you get?

    The "curselection" method is supposed to return a list (of zero, one or more elements, depending on what has been selecteed). If the listbox has "selectmode" set to "single" or "browse", you should get either zero or one element returned, but it still works like getting a list, not like getting a scalar.

    If I'm guessing right about what your code is supposed to do when it works, the "correct" way would be like this:

    ( $what ) = @choices[$dialogLB->curselection]; # or maybe: @what = @choices[$dialogLB->curselection];
    Note the list-context on the left side and "@choices" on the right in both. In the first case, if the listbox happens to have "selectmode" set to "multiple" or "extended", and the user has more than one element selected, only the first element will be assigned to $what. In the second case, @what will have all the selected items (if any). I wasn't able to test this on 5.8.4, but these alternatives do work on 5.8.0, 5.8.1 and 5.8.5.

    I think the mystery here is why your original version "worked" in 5.8.0 -- IMHO, that would have been unexpected, and was probably a bug that got fixed.

Re: Tk warning using curselection() with ActiveState 5.8.4
by zentara (Cardinal) on Sep 30, 2004 at 17:04 UTC
    I wonder if this is the same problem someone had with my Scrolled HList in Tk-POP3-previewer, where esserte said:

    "Interesting. This seems to be another scalar vs. array vs. arrayref change between Tk800 and Tk804. Try the following code in Tk800 and Tk804. The first one shows the stringified array reference, while the second one shows the array.

    perl -MTk -e '$txt = tkinit->Text->pack; $txt->insert("end", [1,2,3]); +MainLoop'
    So to be portable: always write my($result) = $w->method instead of my $result = $w->method (e.g. for Tk::Listbox::curselection) and do not use the arrayref forms where it is possible (e.g. in Tk::Canvas::createLine)."

    I'm not really a human, but I play one on earth. flash japh
Re: Tk warning using curselection() with ActiveState 5.8.4
by Fletch (Bishop) on Sep 30, 2004 at 00:49 UTC

    Perhaps $what = $choices[ @{ $dialogLB->curselection } ]?

      Nope, that returns the size of the list.
      This is what is puzzeling me.
      $choices[ $dialogLB->curselection ] #can't use arr ref as index value $choices[ @{ $dialogLB->curselection } ] #index value is size of array $choices[ @$dialogLB->curselection ] # not an array ref $choices[ $$dialogLB->curselection ] # not an scalar ref
      I don't really mind doing this in two lines, but I don't understand why this used to work but now doesn't.

        How come this no longer works?

        Because you changed your code and added a wantarray perhaps? You are assigning SCALAR context to the return value of your curselection function by using it as an array index. According to Perl it is returning an array ref. This is not a valid index. In your working example you assign ARRAY context to the function call, then that array is evaluated in SCALAR context in the index. Your issue would occur as you say if you had:

        sub curselection { # # was return @array; return wantarray ? @array : \@array; }

        The @$ and $$ issues relate to their precedence being higher than -> so you need @{$a->blah}

        cheers

        tachyon

        Nope, that returns the size of the list.

        The code you give as "your solution":

        @index = $dialogLB->curselection; $what = $choices[@index];
        also uses the size of the returned list as an index.