Skip Menu |

This queue is for tickets about the Graph CPAN distribution.

Report information
The Basics
Id: 43580
Status: resolved
Priority: 0/
Queue: Graph

People
Owner: Nobody in particular
Requestors: chad.a.davis [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.91
Fixed in: (no value)



Subject: Reversed logic on overload::StrVal() in AdjacencyMap::Vertex::__set_path
I am on perl, v5.10.0 built for i486-linux-gnu-thread-multi using Graph 0.91 I was using the Bio::Network::ProteinNet (1.006), which extends your Graph module, with Storable (2.18) when I ran into problems using Storable::retrieve. The deserialised Graph instances reported no neighbors() on any nodes. I traced this back to the 'refvertexed' option. I was using this option, because my nodes are objects and the Graph documentation suggested that this is the proper way to do things. My node objects use overload, to provide stringification. Running through the debugger, I found that refvertexed=>1 results in using Graph::AdjacencyMap::Vertex whereas refvertexed=>0 results in using Graph::AdjacencyMap::Light. The G::A::Light calls my overloaded "" on my node objects, whereas the G::A::Vertex does not call my overloaded "" on my node objects. I inspected G::A::Vertex and found on line 37 (and 78) in version 0.91: my $q = ref $k && ($f & _REF) && overload::Method($k, '""') ? overload::StrVal($k) : $k; I believe this logic to be reversed from what you seem to intend. The overload::StrVal() uses Perl's builtin stringification, providing something like MyNode=HASH(0x972e240) and ignores the stringification I have implemented in my MyNode class. This was the reason e.g. Graph::neighbors() was no longer working after Storable::retrieve(), because the constructed graph object had indexed the nodes by the memory address that they had before they were serialized with Storable::store. I believe the intent is simply: my $q = ref $k && ($f & _REF) && ! overload::Method($k, '""') ? overload::StrVal($k) : $k; ... which would use the objects own stringification, when present, otherwise using Perl's generic stringification of hash references. This is all the attached patch contains. See the script for an example use case. It doesn't use Storable, but it just shows that the node keys in the graph are different when G::A::Vertex is used (via refvertexed=>1), though the node objects provide an overloaded "" in any case. Cheers, Chad
Subject: retrieveVertex.pl
#!/usr/bin/env perl use strict; use warnings; use Graph; use Storable; use Test::More 'no_plan'; use Data::Dumper; use Carp qw/cluck/; package MyNode; use overload ('""' => '_asstring', fallback=>1); sub new { my ($class, %ops) = @_; return bless { %ops }, $class; } sub _asstring { my ($self) = @_; my $str = $self->{'name'}; Carp::cluck("Stringifying $str"); return $self->{'name'}; } 1; package main; my $gnoref = new Graph; my $gwithref = new Graph(refvertexed=>1); my $n1 = new MyNode('name'=>'alpha'); my $n2 = new MyNode('name'=>'beta'); $gnoref->add_edge($n1, $n2); # If you see no further stack traces from cluck, then : print "\nNo more stringification occurs after this point\n\n"; $gwithref->add_edge($n1, $n2); # And then this fails, meaning that Storable is also not usable, because the # nodes are hashed by their memory addresses, which will change on retrieve() is_deeply([sort keys %{$gnoref->[2]->[4]}],[sort keys %{$gwithref->[2]->[4]}]); print "\n"; __END__
Subject: Vertex.diff
--- Vertex.pm.bak 2009-02-24 14:04:57.000000000 +0100 +++ Vertex.pm 2009-02-24 14:06:14.000000000 +0100 @@ -34,7 +34,7 @@ my @p = $p; my @k; my $k = shift; - my $q = ref $k && ($f & _REF) && overload::Method($k, '""') ? overload::StrVal($k) : $k; + my $q = ref $k && ($f & _REF) && ! overload::Method($k, '""') ? overload::StrVal($k) : $k; push @k, $q; return (\@p, \@k); } @@ -75,7 +75,7 @@ my @p = $p; my @k; my $k = shift; - my $q = ref $k && ($f & _REF) && overload::Method($k, '""') ? overload::StrVal($k) : $k; + my $q = ref $k && ($f & _REF) && ! overload::Method($k, '""') ? overload::StrVal($k) : $k; push @k, $q; return (\@p, \@k); }
(Sorry for the long quiet) I'm sorry but I think the code is working as intended. The refvertexed means that the memory address of the reference is used as the "identifier" for the vertex. If I believed the stringified reference, my code could not tell whether "foo" is the same as "foo", or a different "foo". In other words, it's a little bit like a question of believing "values" versus "references". The refvertexed strongly believes the "reference", and ignores the stringified "value". It's a pity that this doesn't scheme seem to interact well with Storable.
That having been said, I think it's possible to add a "new style refvertexed" that behaves as you want.
The new option 'refvertexed_stringified' will be in 0.94.
From: chad.a.davis [...] gmail.com
Thank you for the reply. I've just installed Graph 0.94 and my initial tests are passing. Indeed it must have been a misunderstanding of the intended purpose of 'refvertexed'. The new documentation on refvertexed_stringified is much more clear. Interestingly, I've been using refvertexed=>0 with objects as nodes this whole time and it has been working well with Storable. That seems to make sense, probably because the objects are then just coerced to strings, providing their own stringification. In any case, thank you for the update, Chad