2009-04-26 20 views
7

मान लीजिए कि आपके पास एक बड़ी टीम "डेवेलूपॉप" है;) एक बड़ी टीम द्वारा। यहां संभावित आपदा का सरलीकृत मॉडल है जो तब हो सकता है जब कोई डेटा संरचना में बहुत गहराई से जांच करता है। यदि ऑटोवेफिकेशन पूरी तरह से या दायरे में अक्षम करना संभव नहीं है, तो इसके आसपास कैसे काम करें? बहुत बहुत धन्यवाद :) !!!!मैं पर्ल में ऑटोविविफिकेशन कैसे अक्षम करूं?

$VAR1 = { 
      'akey' => { 
         'deeper' => 1 
        } 
     }; 
Use of uninitialized value in numeric eq (==) at autovivify_test.pl line 5. 
Already in a deep doot 
$VAR1 = { 
      'deep' => {}, 
      'akey' => { 
         'deeper' => 1 
        } 
     }; 

हाँ मैं जानता हूँ कि एक चेतावनी है, लेकिन ... बहुत देर हो चुकी हो सकता है:

use strict; use warnings;use Data::Dumper; 

my $some_ref = {akey=>{deeper=>1}}; 
print Dumper($some_ref); 
if($some_ref->{deep}{doot} == 1){ 
    print 'too deep '.$/; 
} 

if($some_ref->{deep}){ 
    print 'Already in a deep doot'.$/; 
} 

print Dumper($some_ref); 

यह निम्न आउटपुट।

अरे दोस्तों यह कहने में मदद कर सकते हैं कि मेरे हैशफ एक बंधे हैंश संदर्भित करता है।

हो सकता है कि अगर मैं एक अच्छी FETCH विधि लागू करता हूं जो संरचना में गहराई से चेक की जांच करता है, तो मैं आसानी से अपनी समस्या का समाधान करूंगा?


मैं Tie::StrictHash, Tie::Hash और perltie को देखा। मेरी समाधान के यहाँ सरल है संस्करण:

#!/usr/bin/env perl; 
#test_tie.pl 

package StrictHash; 
use strict; use warnings; 
use Tie::Hash; 
our @ISA = qw(Tie::StdHash); 
use Carp; 

sub TIEHASH { 
    my $class = shift; 
    my $hash = bless {@_}, $class; 
    return $hash; 
} 
##======================================================================== 
## FETCH fails if applied to a member that doesn't exist. 
##======================================================================== 
sub FETCH { 
    my ($hash, $key) = @_; 
    Carp::confess "key '$key' does not exist" unless exists $hash->{$key}; 
    return $hash->{$key}; 
} 
##======================================================================== 
package main; 
use strict;use warnings;use Data::Dumper; 
#Imagine StrictHash is in ./StrictHash.pm 
#use StrictHash; 
my %hash; 
tie %hash, 'StrictHash', akey => {deeper=>1} ; 

my $some_ref =\%hash; 
print Dumper($some_ref); 
if($some_ref->{deep}{doot} == 1){ 
    print 'too deep '.$/; 
} 

मैं क्या हासिल अनुप्रयोग में केवल एक ही स्थान पर स्पर्श करने के लिए है। अब सभी जगहें जैसे ($ some_ref -> {deep} {doot}) स्टैक-ट्रेस के साथ मर जाएंगी। तो मैं उन्हें आसानी से ढूंढूंगा और उन्हें सही कर दूंगा। और इस तरह के नए लेखन संभव नहीं होंगे। पर्ल भी बड़े ऐप्स के लिए अच्छा है, आपको बस और जानना होगा;)।

सभी को धन्यवाद! मुझे आशा है कि इससे दूसरों की भी मदद मिलती है।

+0

आपका प्रश्न क्या है? –

+0

मैं पर्ल में ऑटोविविफिकेशन कैसे अक्षम करूं? –

उत्तर

15

हो सकता है कि आप हैश के बजाय किसी ऑब्जेक्ट का उपयोग करना चाहें (Moose देखें) या strict tied hash का उपयोग करें। या फिर आप त्रुटियों में चेतावनी चालू कर सकते हैं, यदि आप वास्तव में चाहते हैं:

use warnings NONFATAL => 'all', FATAL => 'uninitialized'; 
+1

+1, जीत के लिए अनियमित पर FATAL। –

+0

, जैसा कि केंट कहते हैं, चेतावनियों का उपयोग करें NONFATAL => 'all', FATAL => 'uninitialized'; जाने का सबसे स्वीकार्य तरीका है। मैं इसे विकास में स्थापित कर सकता हूं। मैं थोड़ा और सवाल के लिए सवाल छोड़ दूंगा, सिर्फ यह देखने के लिए कि कोई भी कुछ और भी बेहतर सुझाव देगा :)। धन्यवाद। –

+0

मुझे अभी एहसास हुआ कि मुझे अपने फीच विधि में केवल कुछ चेक लिखने की ज़रूरत है क्योंकि मेरे संदर्भ बिंदु वास्तव में एक टाइड हैश के लिए हैं। वास्तव में बहुत बहुत धन्यवाद। –

9

आप हैश Hash::Util से कार्यों में से एक (एक कोर मॉड्यूल) का उपयोग बंद कर सकते हैं।

use Hash::Util qw(lock_keys unlock_keys); 

my $some_ref = { akey => { deeper => 1 } }; 
lock_keys %$some_ref; 

print "too deep" if $some_ref->{deep}{shit} == 1; 

अब पिछले बयान एक अपवाद फेंक देगा:

Attempt to access disallowed key 'deep' in a restricted hash 

नकारात्मक पक्ष यह है, ज़ाहिर है, कि आप जब हैश में कुंजी के लिए जाँच अपवाद से बचने के लिए बहुत सावधान रहना होगा, यानी उन तक पहुंचने से पहले चाबियों की जांच के लिए "if exists ..." का एक लोफ का उपयोग करें।

आप हैश के लिए कुंजी को जोड़ने के लिए की जरूरत है फिर से बाद में आप इसे अनलॉक कर सकते हैं:

unlock_keys %$some_ref; 
$some_ref->{foo} = 'bar'; # no exception 
+0

अच्छा हाँ, लेकिन यह एक बड़ा ऐप है। और कल्पना करें कि हैश एक बंधे सत्र है। धन्यवाद। –

3

मैं @zoul upvoted, लेकिन आप इसे एक कदम और आगे ले जाना चाहिए।

लिखें टेस्ट

आप अपने कोड परीक्षण के साथ कवर किया जाना चाहिए था, और आप

use warnings FATAL => 'uninitialized'; 

परीक्षण मामले में ही घोषित साथ उन लोगों के परीक्षण के कुछ चलाने चाहिए। डेवलपर्स के साथ आपकी चिंता का समाधान करने का यह एकमात्र तरीका है जो चीजों को पहले से ठीक से जांच नहीं रहा है। सुनिश्चित करें कि उनके कोड का परीक्षण किया गया है।

और इसे एक और कदम आगे ले जाएं, और कवरेज रिपोर्ट प्राप्त करने के लिए Devel::Cover के तहत अपने परीक्षण चलाने में आसान बनाएं।

cover -delete 
PERL5OPT='-MDevel::Cover' prove -l 
cover -report Html_basic 

और फिर कोड की लाइनों की जाँच करें और बयान परीक्षण द्वारा क्रियान्वित की जा रही हैं, अन्यथा उन चेतावनियों घातक सिर्फ एक अप्रत्याशित समय बाद में कोड मरने से किया जा सकेगा।

+1

इसके लिए आपको FATAL => 'uninitialized' की आवश्यकता नहीं है। टेस्ट :: चेतावनी मॉड्यूल आपको परीक्षण करने की अनुमति देगा कि आपको अपने परीक्षण मामलों से सही चेतावनियां (या चेतावनियों की अनुपस्थिति) प्राप्त हुई है। –

+0

"लिखें टेस्ट" कहना काफी आसान है :)। मैंने इसे करना शुरू कर दिया, लेकिन जैसा कि आप जानते हैं कि कार्य का इंतजार कर रहे हैं इस बीच मुझे कुछ आसान करने की आवश्यकता है। वोट के लिए धन्यवाद। मैं विकास पर्यावरण में FATAL => 'uninitialized' के साथ जाने पर विचार कर रहा हूं। –

+0

उपयोग चेतावनियों को स्पष्ट रूप से स्कॉप्ड किया गया है, इसलिए परीक्षण में इसे रखने से कोड को परीक्षण में सक्षम नहीं किया जाता है। – ysth

1

एक और विकल्प है अपने डेटा संरचनाओं तक पहुंचने के लिए Data::Diver का उपयोग करना।

no autovivification; 

सुंदर सरल:

if(1 == Dive($some_ref, qw/ deep structures are not autovivified now /) { 
    Do_Stuff(); 
} 
+0

धन्यवाद, मैं बस अपनी समस्या को हल करने और आगे दुर्व्यवहार को बंद करने का एक त्वरित तरीका चाहता था। मैं अपने प्रश्न में समाधान के एक सरलीकृत मॉडल को जोड़ूंगा। –

21

अपेक्षाकृत नया autovivification मॉड्यूल है, जो आपको ऐसा करने की सुविधा देता है है।

+0

मैं इसे आज़माउंगा। क्या यह बंधे हैंश/सरणी के साथ ठीक काम करता है? –

+2

वर्तमान गैर संस्करण निर्भर लिंक: http://search.cpan.org/~vpit/autovivification/ –

+0

धन्यवाद ... प्रतिक्रिया में लिंक अपडेट किया गया। – oeuftete

संबंधित मुद्दे