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.