6

मैं इस तरह पास-दर-संदर्भ कर रहा हूँ:क्या पर्ल में संदर्भ से पास करने का कोई बेहतर तरीका है?

use strict; 
use warnings; 

sub repl { 
    local *line = \$_[0]; our $line; 
    $line = "new value"; 
} 

sub doRepl { 
    my ($replFunc) = @_; 
    my $foo = "old value"; 
    $replFunc->($foo); 
    print $foo; # prints "new value"; 
} 

doRepl(\&repl); 

वहाँ यह करने का एक क्लीनर तरीका है?

प्रोटोटाइप काम नहीं करते हैं क्योंकि मैं फ़ंक्शन संदर्भ का उपयोग कर रहा हूं (मेरा विश्वास करें कि फ़ंक्शन संदर्भ का उपयोग करने का एक अच्छा कारण है)।

मैं repl में हर जगह $_[0] का उपयोग नहीं करना चाहता क्योंकि यह बदसूरत है।

उत्तर

9

आप Data::Alias को देखा है? यह आपको एक साफ वाक्यविन्यास के साथ व्याख्यात्मक-स्कोप्ड उपनाम बनाने देता है।

आप इस तरह पास-दर-संदर्भ अर्थ विज्ञान बनाने के लिए इसका उपयोग कर सकते हैं:

use strict; 
use warnings; 

use Data::Alias; 

sub foo { 
    alias my ($arg) = @_; 
    $arg++; 
} 

my $count = 0; 

foo($count); 

print "$count\n"; 

उत्पादन, 1 है यह दर्शाता है कि foo करने के लिए कॉल अपने तर्क संशोधित।

+0

दुर्भाग्य से, मैंने दस्तावेज़ों के "कार्यान्वयन" अनुभाग को देखा ... एएके! मुझे लगता है कि यह मॉड्यूल सॉसेज की तरह है ... यदि आप नहीं जानते कि उन्हें कैसे बनाया जाता है तो बहुत अधिक आनंददायक ... :) – JoelFan

+0

@ जोएलफ़ान: हाँ। यह बहुत अधिक है "घर पर यह कोशिश न करें" मॉड्यूल :) –

+0

"यह मॉड्यूल स्रोत फ़िल्टर का उपयोग नहीं करता है" शुरू होता है और बस वहां से डाउनहिल चला जाता है ... :) – JoelFan

3

ऐसा करने के कुछ तरीके हैं। स्पष्ट रूप से $foo पर स्केलर रेफरी पास करें, या संदर्भ अर्थशास्त्र द्वारा पर्ल के अंतर्निर्मित पास का लाभ उठाएं।

स्पष्ट संदर्भ:

my $foo = "old value"; 
doRepl(\&repl, \$foo); 
print $foo; # prints "new value"; 

sub repl { 
    my $line = shift; 
    $$line = "new value"; 
} 

sub doRepl { 
    my ($replFunc, $foo) = @_; 
    $replFunc->($foo); 
} 

दर्रा संदर्भ द्वारा:

my $foo = "old value"; 
doRepl(\&repl, $foo); 
print $foo; # prints "new value"; 

sub repl { 
    $_[0] = "new value"; 
} 

sub doRepl { 
    my $replFunc = shift; 
    &$replFunc; 
} 

पहले एक उपयोग सामान्य पर्ल कठिन संदर्भ काम करने के लिए: संदर्भ द्वारा

my $foo = "old value"; 
doRepl(\&repl, $foo); 
print $foo; # prints "new value"; 

sub repl { 
    $_[0] = "new value"; 
} 

sub doRepl { 
    my $replFunc = shift; 
    $replFunc->(@_); 
} 

यहां तक ​​कि अधिक सजावटी पास ।

रेफ विधि द्वारा पहला पास इस तथ्य का उपयोग करता है कि पर्ल सभी कार्यों को संदर्भों के रूप में तर्क देता है। @_ के तत्व वास्तव में तर्क सूची में मानों के लिए उपनाम हैं जब subroutine कहा जाता है। foo() में $_[0] को बदलकर, आप वास्तव में foo() पर पहला तर्क बदलते हैं।

रेफ विधि द्वारा दूसरा पास इस तथ्य का उपयोग करता है कि एक उप & सिगिल के साथ बुलाया जाता है और उसके माता-पिता को @_ कॉलर का सरणी नहीं मिलता है। अन्यथा यह समान है।

अद्यतन: मैंने देखा है कि आप $_[0] से बचने की इच्छा रखते हैं। आप repl में यह कर सकते हैं अगर आप चाहते हैं:

sub repl { 
    for my $line($_[0]) { 
     $line = 'new value'; 
    } 
} 
+0

धन्यवाद ... अच्छी जानकारी, लेकिन मुझे "अंतर्निहित" पास-बाय-रेफ – JoelFan

3

 

sub repl { 
    my $line = \$_[0];  # or: my $line = \shift 
    $$line = "new value"; 
} 
+0

या 'मेरी ($ लाइन) = \ (@_);' –

+0

@ सिनन - अनुमान लगाया नहीं होगा कि काम करेगा। हर दिन कुछ नया सीखना। – mob

+1

नियम देखें http://perldoc.perl.org/perlref.html#Making- संदर्भ "एक विशेष मामले के रूप में, \ \ @ @ foo)' 'foo' की सामग्री के संदर्भों की एक सूची देता है, संदर्भ नहीं '@ foo'' के लिए। –

0

मुझे नहीं लगता कि कुछ भी local का उपयोग कर इस मामले में अन्य नाम बनाना के साथ कुछ गलत है है।

गतिशील दायरा निश्चित रूप से एक शक्तिशाली विशेषता है, लेकिन जब तक आप साइड इफेक्ट्स से अवगत हैं (नए मूल्य को इसके दायरे से बुलाए गए कार्यों में दिखाई देता है, यदि एक ही नाम का एक व्याख्यात्मक दायरा है, तो यह ' टी को स्थानीयकृत नहीं किया जा सकता है ...) तो यह पहले से बहने वाले पर्ल टूलबॉक्स के लिए एक उपयोगी जोड़ है।

पर्ल डॉक्स में local के बारे में चेतावनियों का मुख्य कारण my के बजाय लोगों को अनजाने में रखने और perl4 से संक्रमण को कम करने के लिए है। लेकिन निश्चित रूप से ऐसे समय हैं जब local उपयोगी है, और यह एक है।

अपने उपनाम बनाने के लिए for का उपयोग करना भी एक विकल्प है, लेकिन मुझे अपने इरादे में local स्पष्ट के साथ स्पष्ट वाक्यविन्यास मिलता है। यदि प्रदर्शन चिंता का विषय है तो यह थोड़ा तेज़ भी है।

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

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