Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Why am I getting message «Operation "<=>": no method found,» ?

by RCH (Sexton)
on Aug 01, 2015 at 14:44 UTC ( #1137114=perlquestion: print w/replies, xml ) Need Help??

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

Dear Perl Monks

I'm getting the message

Operation "<=>": no method found, left argument in overloaded package Class::Measure::Length, right argument in overloaded package Class::Measure::Length

from what I thought was just a simple sort

$hash{$b}<=>$hash{$a}

I found a work-around, by sprintf-ing the values in the hash - see code below - but I would like to (try to) understand what is going on.

I'm on Ubuntu 12.04

perl -v says

This is perl 5, version 14, subversion 2 (v5.14.2) built for i686-linux-gnu-thread-multi-64int
The following script gives the no method found message the second time round
use strict; use Carp; use GIS::Distance; my $from_lat = 50.815717; my $from_long = 4.436326; my $to = { Montana => [ 46.536026, -111.935062 ], Correze => [ 45.341874, 1.79531 ], ParisFR => [ 48.850407, 2.347304 ], }; my %distance; foreach my $demo ( 'solution', 'problem' ) { print STDOUT "\n", "-" x 60, "\n\n"; print STDOUT "This is to demonstrate the $demo ...\n"; print STDOUT " Here comes the contents of the hash \%distance\n"; print STDOUT " (distances as calculated by GIS::Distance\n"; if ( $demo eq 'problem' ) { print STDOUT " and stored as that value)\n"; } elsif ( $demo eq 'solution' ) { print STDOUT " and stored as sprintf \"%25.15f\", value )\n"; } foreach my $place ( keys(%$to) ) { my $gis = GIS::Distance->new(); my $to_lat = $to->{$place}->[0]; my $to_long = $to->{$place}->[1]; my $km = $gis->distance( $from_lat, $from_long => $to_lat, $to_long, ); if ( $demo eq 'problem' ) { $distance{$place} = $km; } elsif ( $demo eq 'solution' ) { $distance{$place} = sprintf "%25.15f", $km; } print STDOUT " \$distance{$place} = $distance{$place}\n"; } print STDOUT "\n"; print STDOUT "And here comes the result of sorting the keys of that hash\n"; foreach my $place(sort {$distance{$b} <=> $distance{$a}}( keys(%distance))) { printf STDOUT "%10s is %25.15f km from here\n", $place, $distance{$place}; } }

Replies are listed 'Best First'.
Re: Why am I getting message «Operation "<=>": no method found,» ?
by 1nickt (Abbot) on Aug 01, 2015 at 15:11 UTC

    Use Data::Dumper or similar to examine your data whenever you get something weird like this. Your two hashes are very different. First time through (on solution):

    $VAR1 = { 'ParisFR' => ' 264.965452179665817', 'Montana' => ' 7596.858969274226183', 'Correze' => ' 639.457965193499604' };

    Second time through (problem):

    $VAR1 = { 'ParisFR' => bless( { 'unit' => 'kilometre', 'values' => { 'kilometre' => '264.9654 +52179666' } }, 'Class::Measure::Length' ), 'Montana' => bless( { 'unit' => 'kilometre', 'values' => { 'kilometre' => '7596.858 +96927423' } }, 'Class::Measure::Length' ), 'Correze' => bless( { 'unit' => 'kilometre', 'values' => { 'kilometre' => '639.4579 +651935' } }, 'Class::Measure::Length' ) };
    The way forward always starts with a minimal test.
Re: Why am I getting message «Operation "<=>": no method found,» ?
by Athanasius (Bishop) on Aug 01, 2015 at 15:26 UTC

    Hello RCH,

    As 1nickt says, when $demo has the value 'problem', each element of %distance is a Class::Measure::Length object. So the following fix should work:

    ... print "\nAnd here comes the result of sorting the keys of that has +h\n"; my $sort_function = ($demo eq 'problem') ? sub { $distance{$b}->value <=> $distance{$a}->value } : sub { $distance{$b} <=> $distance{$a} }; for my $place (sort $sort_function keys %distance) { printf "%10s is %25.15f km from here\n", $place, $distance{$pl +ace}; } }

    (Note that Class::Measure::Length inherits most of its methods from Class::Measure.)

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: Why am I getting message «Operation "<=>": no method found,» ?
by poj (Abbot) on Aug 01, 2015 at 15:32 UTC
    Try
    my $km = $gis->distance( $from_lat, $from_long => $to_lat, $to_long, ) ->value('km');
    poj

      Thank you!

      my $km = $gis->distance( $from_lat, $from_long => $to_lat, $to_long, )->value('km');

      Works purrfectly

IGNORE: Re: Why am I getting message «Operation "<=>": no method found,» ?
by 1nickt (Abbot) on Aug 01, 2015 at 14:49 UTC

    Just a guess: Class::Measure::Length is required by GIS::Distance, and overloads (redefines) the <=> operator.


    The way forward always starts with a minimal test.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1137114]
Approved by 1nickt
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (8)
As of 2019-12-09 17:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?