2011-10-12 7 views
12

ठीक है सैनिटी चेक अधिभार के लिए ठीक है मेरे लिए काम नहीं कर रहा है। मुझे नहीं पता कि यह मेरे पास perl का संस्करण है, या overload.pm का संस्करण है, या मैंने इसे कैसे कार्यान्वित किया है, इसके साथ कुछ गलत है, लेकिन यह कोड मेरे लिए काम नहीं करता है।"उपयोग नामस्थान: autoclean" के साथ "अधिभार का उपयोग" क्यों नहीं करता है?

पर्ल संस्करण

This is perl, v5.10.1 (*) built for x86_64-linux-gnu-thread-multi 

अधिभार संस्करण

perl -Moverload -e 'print "$overload::VERSION\n";' 
1.07 

Token.pm

package Token; 
use namespace::autoclean; 
use Data::Dumper; 


use Moose; 
use Moose::Util::TypeConstraints; 

use overload '+' => \&_overload_add, fallback => 1; 

    has 'secretvalue' => (is => 'rw', isa => 'Int'); 

    sub _overload_add{ 
    my ($one, $two) = @_; 
    my $value = $one->secretvalue() + $two->secretvalue(); 
    return ($value); 
    } 

मुख्य

use strict; 
use warnings; 
use Token; 
my $t = Token->new(secretvalue => 17, key => 'x'); 
my $t2 = Token->new(secretvalue => 12, key => 'y'); 

my $x = $t + $t2; 

print $x; 

प्रिंट

$VAR1 = 12900840; 

सबसे बुरी बात यह है कि मैं चेतावनी या लॉग में त्रुटियों के किसी भी प्रकार नहीं मिल रहा है है।

अद्यतन

धन्यवाद समस्या को खोजने के लिए Freido करने के लिए। मैंने सवाल उठाया है अगर किसी और ने इस पर ठोकर खाई है।

क्या पर्ल/मूस समुदाय आमतौर पर ओवरलोड का उपयोग नहीं करता है?

उत्तर

16

namespace::autoclean जादू के साथ futzing है कि overload आपके ऑपरेटर को संभालने के लिए जोड़ता है। निम्नलिखित काम करता है के रूप में आप उम्मीद करेंगे:

package Token; 

use Moose; 
use Moose::Util::TypeConstraints; 

use overload '+' => '_overload_add'; 

has 'secretvalue' => (is => 'rw', isa => 'Int'); 

sub _overload_add{ 
    my ($one, $two) = @_; 
    my $value = $one->secretvalue() + $two->secretvalue(); 
    return ($value); 
} 

1; 

एक आकस्मिक नज़र namespace::autoclean डॉक्स है कि इस के पते में कुछ भी खुलासा नहीं करता है, इसलिए मुझे लगता है कि यह एक अप्रत्याशित सुविधा है। कुछ खोज से पता चलता है कि bug की सूचना दी गई है।

मुझे लगता है कि यह विशेष प्रतीक नीचे आता है कि overload आपके पैकेज में जोड़ता है। + ओवरलोडिंग प्रतीक तालिका प्रविष्टियां (), (+, और OVERLOAD जोड़ती है। मुझे लगता है कि इनमें से कुछ या सभी को namespace::autoclean तक खाली कर दिया गया है, इस प्रकार आपके ओवरलोडिंग को पूर्ववत कर दिया गया है।

यदि आप साहसी महसूस कर रहे हैं, here's a patchnamespace::autoclean के लिए जो ओवरलोड प्रतीकों को फ़िल्टर करता है।

+1

+1 समाधान के लिए +1 जब मैंने डेस्क पर अपने सिर को एक या दो घंटे के लिए मेरे कोड के साथ समस्या को खोजने की कोशिश की। मूर्ख पुस्तकालय कीड़े! – qodeninja

+1

वहां गया, ऐसा किया। :) जब तक मुझे याद नहीं आया कि जादू अधिग्रहण करके 'अधिभार' काम करता है, तब तक मैं आपकी समस्या से काफी परेशान था, और मुझे आश्चर्य हुआ कि क्या 'ऑटोक्लियन' उनके साथ गड़बड़ कर रहा था। – friedo

+3

@nodebunny, जब आप अपना खुद का लिख ​​सकते हैं तो अन्य लोगों के कोड के बारे में शिकायत क्यों करें? :) इस सवाल ने मुझे [नेमस्पेस :: स्वीप] लिखने के लिए प्रेरित किया (http://search.cpan.org/~friedo/namespace-sweep/lib/namespace/sweep.pm) जो आपके ओवरलोड को टंप नहीं करेगा। अधिक जानकारी [यहां] (http://blogs.perl.org/users/mike_friedman/2011/10/announcing-namespacesweep.html)। – friedo

10

तो friedo बिल्कुल सही है; समस्या हेरिस्टिक क्लास :: एमओपी में निहित है यह निर्धारित करने के लिए कि "क्या विधि" क्या है और क्या नहीं है। आम तौर पर, किसी अन्य पैकेज से आयात की गई कोई भी विधि एक विधि नहीं है, और ओवरलोड तकनीकी रूप से योग्यता प्राप्त करते हैं। चूंकि नामस्थान :: autoclean क्लास :: एमओपी से पूछता है कि पैकेज के लिए कौन सी विधियां मौजूद हैं और बाकी को हटा देती हैं, अन्य सभी चीज़ों के साथ autoclean blindly purges overloads को हटा देता है।

जो मुझे लगता है कि आश्चर्यजनक है, मुझे लगता है।

MooseX::MarkAsMethods मूस कक्षाओं के लिए इसके साथ मदद करेगा; यह autoclean करता है इससे पहले चलता है और मूस को उस पैकेज के लिए किसी भी अधिभार कोड प्रतीक पहचानने के लिए कहता है। इससे उन्हें ऑटोक्लियन की कुल्हाड़ी मिलती है, और इसमें अतिरिक्त लाभ होता है कि अब आप भूमिकाओं में ओवरलोड का उपयोग कर सकते हैं, उनका उपभोग कर सकते हैं, और उन्हें "बस काम" कर सकते हैं। (पूर्ण प्रकटीकरण: मैंने अपने ऑटोकलीन फिक्स को 2 साल पहले खारिज कर दिए जाने के बाद एमएक्स :: मार्कएएस मोड्स लिखा था।)

हालांकि, यह गैर-मूस कक्षाओं के साथ मदद नहीं करता है, जिसके साथ आप ऑटोक्लियन का उपयोग करना चाह सकते हैं ... ऑटोक्लियन द्वारा ओवरलोड को हटाने, सबसे अच्छा, ऑटोक्लियन में एक दोष है।

+5

'दोष' बहुत दयालु है, 'नामस्थान :: autoclean' इस वजह से टूट गया है। आपका फिक्स सही बीटीडब्ल्यू था, यह शर्म की बात है कि रखरखाव इसके बारे में जिद्दी है। –

0

मुझे एक ही समस्या है (मेरे मामले में "" अधिभारित करने का प्रयास कर रहा है), लेकिन अभी तक MooseX :: MarkAsMethods को काम करने के लिए नहीं मिला है। ठीक से अभी तक क्यों नहीं देखा गया है, लेकिन एक वैकल्पिक फिक्स है कि काम MooseX::Role::WithOverloading का उपयोग करना था (और चूंकि मैं पहले से ही विभिन्न भूमिकाओं का उपयोग कर रहा था)।

package MyClass; 
use Moose; 
use namespace::autoclean; 
with 'MyRole'; 

package MyRole; 
use MooseX::Role::WithOverloading; 

use overload '""' => sub { ... }; 
संबंधित मुद्दे