उदाहरण के लिए मेरे अपने Test::Versionका सारांश है।.

use Test::More;
use Test::Version 0.04;

# test blib or lib by default
version_all_ok();

done_testing;

मुझे done_testing(); पर कोष्ठक शामिल करने की आवश्यकता नहीं है, मैं बस इसे कॉल कर सकता हूं। हालांकि जब मैंने version_all_ok; को कॉल करने का प्रयास किया (नोट: Dist::Zilla::Plugin::Test::Version पर पहला प्रयास इस तरह विफल रहा) मुझे एक त्रुटि मिलती है। ऐसा क्यों है?

अपडेट करें शायद मेरा उदाहरण उतना अच्छा नहीं है जितना मैंने सोचा था। मुझे मिली वास्तविक त्रुटि है

Bareword "version_all_ok" not allowed while "strict subs" in use at t/release-test-version.t line 19.

और यहाँ पूरा कोड है

#!/usr/bin/perl

BEGIN {
  unless ($ENV{RELEASE_TESTING}) {
    require Test::More;
    Test::More::plan(skip_all => 'these tests are for release candidate testing');
  }
}

use 5.006;
use strict;
use warnings;
use Test::More;

eval "use Test::Version";
plan skip_all => "Test::Version required for testing versions"
    if $@;

version_all_ok; # of course line 19, and version_all_ok() works here.
done_testing;

निर्यात के लिए Test::Version 1.0.0 से लिए गए प्रासंगिक स्निपेट निम्नलिखित होने चाहिए।

use parent 'Exporter';
our @EXPORT = qw( version_all_ok ); ## no critic (Modules::ProhibitAutomaticExportation)
our @EXPORT_OK = qw( version_ok );
10
xenoterracide 22 जुलाई 2011, 07:51

6 जवाब

सबसे बढ़िया उत्तर

मूल रूप से, क्योंकि पर्ल को यह जानने की जरूरत है कि फ़ंक्शन कॉल के रूप में इसे पार्स करने के लिए एक नंगे शब्द का अर्थ फ़ंक्शन कॉल है। पर्ल इस दिलचस्प तथ्य को दो तरीकों से सीख सकता है:

  1. आपने बेयरवर्ड को फ़ंक्शन कॉल की तरह सजाया होगा, & या -> या (...) या दोनों को जोड़कर। पर्ल भरोसा करेगा कि आप जानते हैं कि आप किस बारे में बात कर रहे हैं और फ़ंक्शन कॉल के रूप में बेयरवर्ड को पार्स करें, भले ही उसे अभी तक पता न हो कि उसे किस फ़ंक्शन को कॉल करना होगा।

  2. पर्ल कॉल को पार्स करने का प्रयास करने से पहले आपने उस नाम के साथ एक फ़ंक्शन घोषित कर दिया होगा। आमतौर पर, use-एक मॉड्यूल में यह सुनिश्चित करने के लिए पर्याप्त है कि प्रतीकों को सही समय पर बनाया जाए; आप Test::Version में कुछ गलत कर रहे हैं जैसे कि परीक्षण स्क्रिप्ट को संकलित करने के लिए आवश्यक होने तक प्रतीक निर्यात नहीं किया जा रहा है।

अपने कोड में, आप use को eval के अंदर लपेटते हैं, जो इसे निष्पादन समय तक प्रभावी रूप से विलंबित करता है। नतीजतन, प्रतीक version_all_ok उपलब्ध नहीं है जब पर्ल कॉल को संकलित करने का प्रयास करता है और यह उड़ जाता है। प्रतीक को उपलब्ध कराने के लिए eval को समय संकलित करने के लिए बाध्य करना पर्याप्त होना चाहिए:

BEGIN {
    eval "use Test::Version";
    plan skip_all => "Test::Version required for testing versions"
        if $@;
}
15
darch 23 जुलाई 2011, 02:50

यह उदाहरण दिखाता है (स्पष्ट रूप से मुझे लगता है) कि आपको केवल फ़ंक्शन को पूर्वनिर्धारित करना है।

#!/usr/bin/env perl

use strict;
use warnings;

sub hi {
  print "hi\n";
}

hi; #could be `hi();`
bye();  #could not be `bye;`

sub bye {
  print "bye\n";
}

यदि आपकी संवेदनशीलता के लिए आवश्यक है कि आप अपने सबरूटीन्स को नीचे परिभाषित करें, लेकिन आप चाहते हैं कि वे बिना माता-पिता के कॉल करने योग्य हों (जैसे कि पूर्व-घोषित), तो आप subs प्रज्ञा:

#!/usr/bin/env perl

use strict;
use warnings;

use subs qw/hi bye/;

hi;
bye;

sub hi {
  print "hi\n";
}

sub bye {
  print "bye\n";
}

अपडेट करें: ऐसा प्रतीत होता है कि subs प्राग्मा स्ट्रिंग इवल्स की समस्याओं को भी कम कर सकता है। आप अपनी स्क्रिप्ट के शीर्ष के पास एक use subs 'version_all_ok'; आज़मा सकते हैं। मेरी अवधारणा का प्रमाण:

#!/usr/bin/env perl

use strict;
use warnings;

use subs qw/hi bye/;

eval <<'DECLARE';
sub bye {
  print "bye\n";
}
DECLARE

hi;
bye;

sub hi {
  print "hi\n";
}
4
Joel Berger 23 जुलाई 2011, 00:53

मैं टेस्ट :: संस्करण 1.0.0 या 0.04 का उपयोग करके इसे डुप्लिकेट नहीं कर सकता। क्या यह संभव है कि आप वह निर्यात नहीं कर रहे थे जो आपने सोचा था?

क्या आप असफल होने वाली पूर्ण स्क्रिप्ट, त्रुटि संदेश, और पूर्ण स्क्रिप्ट जो सफल हुई, और आप जिस पर्ल संस्करण का उपयोग कर रहे हैं, दोनों को दोबारा जांच और प्रदान कर सकते हैं?

अपडेट करें: ठीक है, आप रनटाइम पर टेस्ट :: संस्करण लोड कर रहे हैं; इसका मतलब है कि जब संकलन समय पर version_all_ok का सामना करना पड़ता है, तो ऐसा कोई सबरूटीन नहीं होता है। परीक्षण स्क्रिप्ट को किसी तरह से संशोधित किए बिना इसके आसपास कोई रास्ता नहीं है, जैसे:

my $has_test_version;
BEGIN { $has_test_version = eval "use Test::Version; 1" }
plan skip_all => "Test::Version required for testing versions" if ! $has_test_version;
2
ysth 23 जुलाई 2011, 00:23

इसे आपके उपयोग से पहले घोषित करने की आवश्यकता है, फिर भी कोष्ठक या एम्परसेंड का उपयोग भेद और स्पष्टता के लिए किया जाना चाहिए।

0
user802675user802675 22 जुलाई 2011, 09:09

यदि फ़ंक्शन को पहले घोषित किया गया है, तो इसकी अनुमति है, और इसे एक सूची ऑपरेटर के रूप में माना जाएगा (चेतावनी: यह ऑपरेटर की प्राथमिकता को बदल सकता है!)

-1
LeleDumbo 22 जुलाई 2011, 08:29

प्रोग्रामिंग पर्ल से, अध्याय 29 कार्य:

पूर्वनिर्धारित पर्ल फ़ंक्शंस का उपयोग या तो उनके तर्कों के आसपास या बिना कोष्ठक के किया जा सकता है; इस अध्याय में वाक्य रचना सारांश कोष्ठक को छोड़ देते हैं। यदि आप कोष्ठक का उपयोग करते हैं, तो सरल लेकिन कभी-कभी आश्चर्यजनक नियम यह है: यदि यह एक फ़ंक्शन की तरह दिखता है, तो यह एक फ़ंक्शन है, इसलिए प्राथमिकता कोई मायने नहीं रखती। अन्यथा, यह एक सूची ऑपरेटर या यूनरी ऑपरेटर है, और प्राथमिकता मायने रखती है। सावधान रहें, क्योंकि यदि आप कीवर्ड और उसके बाएं कोष्ठक के बीच खाली स्थान रखते हैं, तो भी यह एक फ़ंक्शन होने से नहीं रोकता है

P.677 को मिला (Google पुस्तकें कॉपीराइट के कारण) -- प्रत्येक पर्ल प्रोग्रामर के पास कैमल बुक होनी चाहिए।

-2
vol7ron 23 जुलाई 2011, 21:09