0

Brain getting foggy on this one. I wanted to take my dice game from using rand() to using a list of random values from random.org. I was able to retrieve the values just fine, I'm just hung up on the syntax to pop from the list.

Here's my function that's giving me fits:

sub roll_d
{
  return (pop($$dice_stack{@_[0]}));
  # Original code:
  #return (int(rand @_[0]) + 1);
}

Where $dice_stack is a pointer to a hash where the key is the dice type ('6' for d6, '20' for d20), and the value is an array of integers between 1 and the dice type.

matthias krull
  • 4,389
  • 3
  • 34
  • 54
coding_hero
  • 1,759
  • 3
  • 19
  • 34
  • 1
    It would help if you posted exact error you get AND exact contents of $dice_stack from `Data::Dumper`. It's possible to guess what the heck is under the hood but we shouldn't have to guess. – DVK Aug 29 '11 at 19:09
  • The warning caused by `@_[0]` can be avoided using the more proper `$_[0]`. – ikegami Aug 29 '11 at 20:19

2 Answers2

7

$$dice_stack{@_[0]} - aka $dice_stack->{@_[0]} - is a VALUE in a hashref. As such, it will necessarily be a scalar and can't be a poppable-from-array.

If the value is an array reference, you need to de-reference:

  return ( pop(@{ $dice_stack->{ @_[0] } }) );

If it's NOT an arrayref, you need to access it in some other way.

Also, this is starting to look golfish - at this point of line noisiness, I would recommend switching to more readable code (IMHO):

  my ($dice_type) = @_;
  my $dice_list = $dice_stack->{$dice_type};
  return pop(@$dice_list);
DVK
  • 126,886
  • 32
  • 213
  • 327
  • Aha, you are correct, sir. Left out that part on my description (and in my code, apparently). Thank you. – coding_hero Aug 29 '11 at 19:13
  • 5
    Just a note: Starting with Perl 5.14, "pop" can take a scalar EXPR, which must hold a reference to an unblessed array. The argument will be dereferenced automatically. This aspect of "pop" is considered highly experimental. The exact behaviour may change in a future version of Perl. – Joel Berger Aug 29 '11 at 19:51
  • 1
    @Joel: I’m rather unfond of that “feature”, as it doesn’t autovivify with push the way it should. – tchrist Aug 30 '11 at 07:11
  • 1
    @Joel: `push $cities{$state}, $city;` won’t autoviv. You still have to use `push @{ $cities{$state} }, $city;` the first time. It’s dumb. – tchrist Aug 30 '11 at 13:25
  • @tchrist, ok so `push` is a little screwy (do you think that this will be addressed in the future?), still `pop` should be ok don't you think? – Joel Berger Aug 30 '11 at 14:34
1

Try dereferencing the array first:

pop(@{$dice_stack{@_[0]}})
ennuikiller
  • 46,381
  • 14
  • 112
  • 137