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

Hi, For some reason I cannot get Cache::Memcached::Fast to work with arrays. Arrays of hashes work okay, but arrays them selves do not. Scalars are also ok. Doesn't work, as per online documentation:
use Cache::Memcached::Fast; $memd = new Cache::Memcached::Fast({ servers => [ { address => 'localhost:11211', weight => 2.5 } ], namespace => 'abc:', connect_timeout => 0.2, io_timeout => 1.0, close_on_error => 1, compress_threshold => 100_000, compress_ratio => 0.9, compress_algo => 'deflate', max_failures => 3, failure_timeout => 2, ketama_points => 100, nowait => 0, serialize_methods => [ \&Storable::freeze, \&Storable::thaw ], utf8 => ($^V >= 5.008001 ? 1 : 0), }); $memd->flush_all; @array = (1,2,3,4); $memd->set("mem_id_cache",\@array); @tmp = $memd->get("mem_id_cache"); foreach (@tmp){ print $_; }
All it does is print ARRAY(0x1b316c0)ARRAY(0x1e82f48)ARRAY(0x19913a0) If I inspect what was actually stored in memcache:
telnet localhost 11211 get abc: mem_id_cache VALUE abc:mem_id_cache 1 32 + + 12345678 1 2 3 4 END
Help on this is much appreciated.

Replies are listed 'Best First'.
Re: Memcached and arrays?
by ikegami (Patriarch) on Jan 21, 2010 at 05:37 UTC

    If you're having a problem, stop hiding the diagnostics. Use use strict; use warnings;! They wouldn't have helped here (except to detect unrelated issues), but you didn't know that.

    I love how you repeat that it works for arrays and it doesn't work for arrays. The problem is surely in the question.

    Your code is equally fishy.

    $memd->set("mem_id_cache", \@array); ^^^^^^^ scalar @tmp = $memd->get("mem_id_cache"); ^^^^ array

    Why do you expect to get something different than you put in?

    Storing @array yeilds nothing.

    I'm curious as to how you tested that since functions can only take scalars as arguments.

    Passing the contents of the array is obviously wrong too, since the documentation that says you must supply *a* scalar for the value.

    Since you can't change what you store, you need to change what you expect to fetch.

    my @items_to_stored = qw( a b c ); $memd->set("mem_id_cache", \@items_to_stored); my $stored_items = $memd->get("mem_id_cache"); print "$_\n" for @$stored_items;
      my @items_to_stored = qw( a b c ); $memd->set("mem_id_cache", \@items_to_stored); my $stored_items = $memd->get("mem_id_cache"); print "$_\n" for @$stored_items;

      Surely, that would only work, if at all, if you retrieve the array ref in the same process as you stored it. Otherwise the reference would just point to some random chunk of (probably unallocated) memory.

      And what is the point of storing a ref in a cache then retreiving it, when you have direct access to the data it points to?


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        No, it serialises and deserialises data structures for you (using Storable::freeze and Storable::thaw by default). $stored_items holds a reference to a copy of the original array.

        This was a simple test if I could actually store results in Memcached then retrieve them at a later time. Success!
      I thought subroutines can accept arrays then passed to @_? The plan was to use this code segment once working in a larger context.
      sub mem_get{ my $tmp = $memd->get($_[0]); if (ref($tmp) eq "ARRAY"){ return @{$tmp}; }else{ return $tmp; }

        I thought subroutines can accept arrays then passed to @_

        That sentence is a contradiction. Array element can only be scalars, so @_ can't contain an array. It can only contain a reference to one since a reference is a scalar.

        In

        foo(@a)

        @a evaluates to its content, and those are used as the arguments. The above is the same as

        foo($a[0], $a[1], $a[2], $a[3]);

        The plan was to use this code segment once working in a larger context.

        Careful

        my $old_x = [qw( a b c )]; $memd->set(x => $x); my $new_x = mem_get('x'); # $new_x = 3 !?
Re: Memcached and arrays?
by ww (Archbishop) on Jan 21, 2010 at 04:28 UTC
      Upon further investigation it seems the values are being stored correctly. Thus I have no clue why @tmp = $memd->get("mem_id_cache") only returns the reference. This code seems to have worked.
      $tmp = $memd->get("mem_id_cache"); @tmp = @{$tmp};

        Because that's what you stored.

        Also, @tmp = @{$tmp}; makes a needless copy of the array. Just use $tmp instead of @tmp.

      Thanks for your reply. Storing @array yeilds nothing. Hashes and arrays of hashes seem to work fine. http://search.cpan.org/~kroki/Cache-Memcached-Fast-0.07/lib/Cache/Memcached/Fast.pm