कुछ उपयोगकर्ता पर्ल में क्लास के नाम क्यों उद्धृत करते हैं?


12

Type::Tinyमुझे देखते हुए , मैं देख रहा हूं कि कॉल में वर्ग का नाम Type::Tiny->newआधिकारिक डॉक्स में उद्धृत किया गया है,

my $NUM = "Type::Tiny"->new(
   name       => "Number",
   constraint => sub { looks_like_number($_) },
   message    => sub { "$_ ain't a number" },
);

ऐसा क्यों है? क्या यह मात्र शैली है? क्या इस अभ्यास के लिए कोई प्रदर्शन प्रभाव है?

जवाबों:


7

एक सरल उदाहरण लें

package Foo { sub new { die 7  } };
package Bar { sub new { die 42 } };
sub Foo { "Bar" }
Foo->new();

उपरोक्त उदाहरण में, निरंतर Foo"बार" को हल करता है, इसलिए यह कॉल "Bar"->newनहीं करता है "Foo"->new। आप सबरूटिन को कैसे हल करने से रोकते हैं? आप इसे उद्धृत कर सकते हैं।

"Foo"->new();

प्रदर्शन निहितार्थ के रूप में, चीजें नंगे की बजाय स्ट्रिंग का उपयोग करके खराब नहीं की जाती हैं। मैंने पुष्टि की है कि ऑप्ट्री द्वारा उत्पन्न O=Deparseसमान है। एक सामान्य नियम के रूप में, यदि आप शुद्धता को महत्व देते हैं, तो क्लासनाम का उद्धरण देना बेहतर होगा।

यह प्रोग्रामिंग पर्ल में उल्लेख किया गया है, (दुख की बात अप्रत्यक्ष विधि के आह्वान के संदर्भ में )

... तो हम आपको बताएंगे कि आप लगभग हमेशा एक नंगे वर्ग के नाम से दूर हो सकते हैं, बशर्ते दो चीजें सच हों। पहला, वर्ग के समान नाम का कोई उप-समूह नहीं है। (यदि आप उस अधिवेशन का अनुसरण करते हैं, जो उप-नाम जैसे newलोअरकेस शुरू करते हैं और क्लास के नाम जैसे ElvenRingअपरकेस शुरू करते हैं , तो यह कभी समस्या नहीं है)। दूसरा, कक्षा एक से भरी हुई है

use ElvenRing;
require ElvenRing;

या तो इन घोषणाओं से यह सुनिश्चित होता है कि पर्ल को पता ElvenRingहै कि एक मॉड्यूल नाम है, जो किसी भी नंगे नाम को मजबूर करता है जैसे newकि क्लास नाम ElvenRingसे पहले एक विधि कॉल के रूप में व्याख्या की जा सकती है, भले ही आप newवर्तमान पैकेज में अपनी खुद की सबरूटीन घोषित करने के लिए हो ।

और, यह समझ में आता है: यहां भ्रम केवल तभी हो सकता है जब आपके सबरूटीन्स (आमतौर पर लोअरकेस) का एक वर्ग (आमतौर पर अपरकेस) के समान नाम होता है। यह केवल तभी हो सकता है जब आप उस नामकरण सम्मेलन का उल्लंघन करते हैं।

tldr; यह शायद अपने सहकर्मियों को उद्धृत करने के लिए एक अच्छा विचार है, अगर आप उन्हें जानते हैं और आप अव्यवस्था पर शुद्धता को महत्व देते हैं।

साइड नोट: वैकल्पिक रूप से आप ::इसके अंत तक, उदाहरण के लिए, इसे चिपकाकर किसी कार्य के लिए किसी नंगेपन के संकल्प को रोक सकते हैं Foo::->new


मेरे लिए इसे इंगित करने के लिए Reddit पर Ginnz और टिप्पणी के लिए टोबी इंकस्टर को धन्यवाद (हालांकि यह पहली बार पढ़ने पर मुझे समझ नहीं आया)।


2
या Foo::->new, जैसा कि मैंने ikegami से सीखा है।
भीड़

@ एमओबी येल, पर्ल बुक में उल्लेख किया गया है कि स्पष्ट रूप से भी, सुनिश्चित नहीं है कि मुझे वहाँ रखना चाहिए या नहीं? जबरदस्त हंसी।
इवान कैरोल

@ मब ने मुझे भी फुटनोट के रूप में जोड़ा। हालांकि मुझे यकीन नहीं है कि मुझे यह पसंद है।
इवान कैरोल

1
Foo::फायदा है कि अगर यह Fooमौजूदा पैकेज नहीं है तो चेतावनी देता है
ikegami

1
कोशिश करें: टिनी फू से बेहतर उदाहरण है। आपके कोड का उपयोग करके Foo->आपको यह जानने की उम्मीद की जा सकती है कि आपके पैकेज में ऐसा कोई सबरूटीन नहीं है। लेकिन अगर आप ट्राई कर रहे हैं :: टिनी और कई अन्य cpan / अन्य बाहरी रूप से खट्टे मॉड्यूल, जो यह कहना चाहते हैं कि उनमें से कोई एक ट्राई पैकेज का उपयोग कर रहा है, और यदि ऐसा है, तो इसमें टिनी उप है?
ysth

0

स्पष्ट रूप से नंगे शब्द (जिसे एक स्ट्रिंग के रूप में माना जाता है) का उपयोग करने के बजाय कक्षा के नाम को उद्धृत करना सिंटैक्टिक अस्पष्टता से बचने के तीन तरीकों में से एक है। लागू कक्षा के तरीके की धारा perlobj प्रलेखन बताते हैं।

क्योंकि पर्ल आपको पैकेज के नाम और सबरूटीन नामों के लिए नंगे पासवर्ड का उपयोग करने की अनुमति देता है, यह कभी-कभी गलत तरीके से नंगेपन के अर्थ की व्याख्या करता है। उदाहरण के लिए, निर्माण की Class->new()व्याख्या 'Class'->new()या तो की जा सकती है Class()->new()। अंग्रेजी में, दूसरी व्याख्या के रूप में लिखा जाता है कि "एक सबरूटीन को Class()कॉल करें, फिर new()वापसी के मूल्य पर एक विधि के रूप में कॉल करें Class()।" यदि Class()वर्तमान नामस्थान में एक सबरूटीन नाम है, तो पर्ल हमेशा Class->new()दूसरे विकल्प के रूप में व्याख्या करेगा : कॉल new()पर लौटी वस्तु पर कॉल Class()

नीचे डेमो के साथ कार्रवाई में इस विषम मामले को देखें।

#! /usr/bin/env perl

use strict;
use warnings;

sub Type::Tiny { print "Returning Bogus\n" ; return "Bogus" }

sub Type::Tiny::new { print "Type::Tiny::new\n" }

sub Bogus::new { print "Bogus::new\n" }

my $class = "Type::Tiny";

Type::Tiny->new;
Type::Tiny::->new;
"Type::Tiny"->new;
$class->new;

इसका आउटपुट है

बोगस लौटना
नकली :: नई
प्रकार :: टिनी :: नई
प्रकार :: टिनी :: नई
प्रकार :: टिनी :: नई

बाकी उल्लिखित प्रलेखन खंड दिखाता है कि आश्चर्यजनक व्यवहार या अनजाने त्रुटियों से कैसे बचाव किया जाए।

आप पर्ल को दो तरीकों से पहली व्याख्या ( अर्थात , कक्षा नाम की विधि के रूप "Class"में) का उपयोग करने के लिए बाध्य कर सकते हैं। सबसे पहले, आप ::वर्ग के नाम में एक संलग्न कर सकते हैं :

Class::->new()

पर्ल हमेशा एक विधि कॉल के रूप में इसकी व्याख्या करेगा।

वैकल्पिक रूप से, आप वर्ग का नाम उद्धृत कर सकते हैं:

'Class'->new()

बेशक, अगर क्लास का नाम स्केलर में है, तो पर्ल सही काम भी करेगा:

my $class = 'Class';
$class->new();

आपके प्रश्न पर लागू, नीचे दी गई सभी कॉल समतुल्य हैं।

Type::Tiny::->new(  );

"Type::Tiny"->new(  );

my $class = "Type::Tiny";
$class->new(  );

::अंत में आवेदन करने से एक सहायक चेतावनी के उत्पादन का लाभ होता है। आप गलती से टाइप करें

Type::Tinny::->new;

वह पैदा करता है

बेयरवर्ड "टाइप :: टिन्नी ::" ./try लाइन 15 पर कोई भी स्थिर पैकेज को संदर्भित नहीं करता है।
पैकेज के माध्यम से ऑब्जेक्ट विधि "नया" का पता नहीं लगा सकते हैं "टाइप :: टिननी" (शायद आप "टाइप :: टिननी?) लोड करना भूल गए हैं ।/try लाइन 15 पर।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.