Node.js REPL के साथ एक फ़ंक्शन को क्यों कॉल करता है) (काम?


191

नोड में फ़ंक्शन को इस तरह से कॉल करना क्यों संभव है, नोड.जेएस के साथ परीक्षण किया गया:

~$ node
> function hi() { console.log("Hello, World!"); };
undefined
> hi
[Function: hi]
> hi()
Hello, World!
undefined
> hi)( // WTF?
Hello, World!
undefined
>

अंतिम कॉल hi)(, काम क्यों करता है ? क्या यह नोड में बग है। Vs, V8 इंजन में बग, आधिकारिक तौर पर अपरिभाषित व्यवहार, या वास्तव में सभी दुभाषियों के लिए मान्य जावास्क्रिप्ट है?


1
Ubuntu 13.04 पर नोड्ज v0.6.19 में प्रजनन योग्य
— mvp

1
jsfiddle.net पर एक त्वरित परीक्षण आपको दिखाएगा कि यह अमान्य जावास्क्रिप्ट है।
— क्रिस्टोफ

6
लगता है कि एक नोड REPL बग हो सकता है, दो पंक्तियों को एक .jsवाक्यविन्यास त्रुटि का कारण होगा
— leesei

8
Btw, क्रेडिट जहाँ यह होने वाला है, यह irc (FreeNode #nodejs) पर आया, @miniml द्वारा
— hyde

3
पर्ल के पास समान कारण के लिए कुछ समान है perl -ne '$x += $_; }{ print $x':। पर्ल की छिपी विशेषताएं
— एड्रियन प्रोक

जवाबों:


84

लगता है कि एक नोड REPL बग हो सकता है, इन दो लाइनों को डालने से .jsवाक्यविन्यास त्रुटि होगी।

function hi() { console.log("Hello, World!"); }
hi)(

त्रुटि:

SyntaxError: Unexpected token )
    at Module._compile (module.js:439:25)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:901:3

अंक # 6634 जमा किया ।

V0.10.20 पर पुन: प्रस्तुत किया गया।


v0.11.7 ने यह तय किया है।

$ nvm run 0.11.7
Running node v0.11.7
> function hi() { console.log("Hello, World!"); }
undefined
>  hi)(
SyntaxError: Unexpected token )
    at Object.exports.createScript (vm.js:44:10)
    at REPLServer.defaultEval (repl.js:117:23)
    at REPLServer.b [as eval] (domain.js:251:18)
    at Interface.<anonymous> (repl.js:277:12)
    at Interface.EventEmitter.emit (events.js:103:17)
    at Interface._onLine (readline.js:194:10)
    at Interface._line (readline.js:523:8)
    at Interface._ttyWrite (readline.js:798:14)
    at ReadStream.onkeypress (readline.js:98:10)
    at ReadStream.EventEmitter.emit (events.js:106:17)
> 

27
वे वास्तव में आगे बढ़े और इसे तय किया? Awwww, दया, मैं वास्तव में इसे एक संस्कृति शुरू करना और सभी भाषाओं में एक विशेषता बनना चाहूंगा । मैंने कितनी बार टाइप किया है) (जल्दी में () के बजाय ... :))
— जियोमागास

18
@geomagas आपको लगता है कि function a)arg1, arg2( } ]arg2 + arg1[ return; {मान्य सिंटैक्स होना चाहिए?
— azz

40
नहीं वास्तव में नहीं। दरअसल, यह एक मजाक था।
— जियोमागास

7
एक बार एक DWIM विकल्प के साथ एक लिस्प कार्यान्वयन था जो स्वचालित रूप से गलत वर्तनी और अन्य छोटी त्रुटियों को ठीक करता था। en.wikipedia.org/wiki/DWIM
— Barmar

2
@geomagas, ठीक है, कुछ पहले से ही आगे बढ़ चुके हैं और इसके बारे में सोचा है - npmहै install और isntall । शर्त आपने ध्यान नहीं दी :)
— एलिरन मलका

201

यह इस कारण से है कि REPL इनपुट का मूल्यांकन कैसे करता है, जो अंततः है:

(hi)()

अतिरिक्त कोष्ठक को अभिव्यक्ति के लिए बाध्य करने के लिए जोड़ा जाता है :

  // First we attempt to eval as expression with parens.
  // This catches '{a : 1}' properly.
  self.eval('(' + evalCmd + ')',
      // ...

आशय एक खंड के बजाय शाब्दिक / प्रारंभिक के{...} रूप में व्यवहार करना है ।Object

var stmt = '{ "foo": "bar" }';
var expr = '(' + stmt + ')';

console.log(eval(expr)); // Object {foo: "bar"}
console.log(eval(stmt)); // SyntaxError: Unexpected token :

और, जैसा कि लीसी ने उल्लेख किया है, इसे 0.11.x के लिए बदल दिया गया है, जो कि सभी इनपुट के बजाय सिर्फ{ ... } लपेटेगा :

  if (/^\s*\{/.test(evalCmd) && /\}\s*$/.test(evalCmd)) {
    // It's confusing for `{ a : 1 }` to be interpreted as a block
    // statement rather than an object literal.  So, we first try
    // to wrap it in parentheses, so that it will be interpreted as
    // an expression.
    evalCmd = '(' + evalCmd + ')\n';
  } else {
    // otherwise we just append a \n so that it will be either
    // terminated, or continued onto the next expression if it's an
    // unexpected end of input.
    evalCmd = evalCmd + '\n';
  }

19
क्या इसका मतलब है कि hi)(argकाम करेगा? कि कुछ सही मायने में डब्ल्यूटीएफ-ग्रस्त कोड ;-)
— डॉक्टर जोन्स

मुझे अभी तक समझ नहीं आया कि ऐसा क्यों चलेगा। यह बेजोड़ खुला परेड की वजह से एक वाक्यविन्यास त्रुटि नहीं होगा?
— पीटर ओल्सन

2
hi)(argबन जाता है (hi)(arg)- बेमिसाल कुछ भी नहीं
— शीटजेएस

60

4 महीने पहले बग को उठाया गया था, इस मुद्दे के लिए https://github.com/joyent/node/issues/5698

और समस्या यह थी कि, आरईपीएल ने परेंस के साथ बयानों को संलग्न किया। इसलिए

foo)(

हो जाता है

(foo)()

वास्तविक विवरण यहां पाया जा सकता है https://github.com/joyent/node/issues/5698#issuecomment-19487718 ।


75
और मुझे लगा कि स्वचालित अर्धविराम प्रविष्टि खराब थी।
— एरिक लिपर्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.