
मैंने PHP में अजगर-शैली सज्जाकारों को लागू करने के लिए अपनी दृष्टि और सर्वोत्तम प्रथाओं को साझा करने का निर्णय लिया।
एक लालच के रूप में, दाईं ओर की छवि में उपयोग का एक छोटा सा उदाहरण। आउटपुट (सज्जाकार के तर्क को स्वयं लागू करने के बाद):
लॉग: कॉलिंग बी ()
इंट (42)
कार्यान्वयन सी एक्सटेंशन के रूप में किया गया है और पीएचपी के पुनर्निर्माण की आवश्यकता नहीं है। लेकिन यह उन साइटों को होस्ट करना शुरू नहीं करता है जहाँ आप अपने so'shku को डाउनलोड नहीं कर सकते हैं।
फिलहाल, कोड बीटा में है (सभी आवश्यक कार्यक्षमता लिखी गई है, लेकिन संभवतः बग और मेमोरी लीक हैं :))। तो जैसा है। खैर, अगर विकास में मदद करने की इच्छा है, तो मुझे
जीथब पर कमिट स्वीकार करने में खुशी होगी।
एक साधारण उपयोग मामला:
<?php function double($func) { return function() use($func) { return 2*call_user_func_array($func, func_get_args()); }; } @double function a() { return 21; } var_dump(a());
सज्जाकार हमेशा फ़ंक्शंस होते हैं जो फ़ंक्शंस लौटाते हैं। एक बाहरी फ़ंक्शन पहले पैरामीटर के रूप में एक विकल्प फ़ंक्शन को स्वीकार करता है। अजगर के विपरीत, मापदंडों के साथ एक डेकोरेटर को एक फ़ंक्शन के रूप में वर्णित नहीं किया जाता है जो एक फ़ंक्शन देता है जो एक फ़ंक्शन देता है ... अतिरिक्त पैरामीटर बस बदले गए फ़ंक्शन के बाद पास किए जाते हैं:
<?php function add($func, $v=0) { return function() use($func, $v) { return $v+call_user_func_array($func, func_get_args()); }; } @add(1) function a() { return 1; } var_dump(a());
डेकोरेटर्स को जोड़ा जा सकता है:
<?php function dec($func, $p='[]') { return function() use($func, $p) { $s = call_user_func_array($func, func_get_args()); return $p[0].$s.$p[1]; }; } @dec function a() { return 'I'; } var_dump(a()); @dec('{}') function b() { return 'am'; } var_dump(b()); @dec @dec('()') @dec('{}') function c() { return 'here'; } var_dump(c());
इसके अलावा, वे रिवर्स ऑर्डर में किए जाते हैं:
@A
@B
@C
समारोह एक्स
में बदल जाता है
A (B (C (X (...)))
मापदंडों और उनके प्रकारों की संख्या मनमानी है, और गणनाओं का आलस्य आमतौर पर हाथों को खोल देता है:
<?php class Logger { const INFO = 'INFO'; public static function log($func, $text='', $level=self::INFO, $prefix='') { return function() use($func, $text, $level, $prefix) { printf("%s%s: %s\n", $prefix, $level, $text); return call_user_func_array($func, func_get_args()); }; } } @Logger::log('calling a()', Logger::INFO, date('Ymd H:i:s').': ') function a() { return 'Hello'; } var_dump(a());
डेकोरेटर के नाम फ़ंक्शंस और स्टेटिक तरीके होने चाहिए, इसके अलावा, कॉल के समय घोषित किए जाने चाहिए, और डेकोरेटर का वर्णन करते समय नहीं। और सामान्य तौर पर, आप प्रयोग कर सकते हैं:
<?php class Arr { public static function map($func, $cb) { return function() use($func, $cb) { $v = call_user_func_array($func, func_get_args()); return array_map($cb, $v); }; } } class Foo { @Arr::map(function($i){return -$i;}) public function bar() { return range(1, 3); } } $foo = new Foo(); print_r($foo->bar());
खैर, मुझे यकीन है कि हर कोई अपने कार्यों के संदर्भ में कुछ और दिलचस्प बात कर सकता है।
तकनीकी मुद्दे
फिलहाल, मैंने डेकोरेटर के साथ कोड निष्पादित करते समय समर्थन की जांच की:
- cat file.php | php |
- php file.php
- आवश्यकता / शामिल है
- eval
शायद कुछ और याद आ रहा है।
ज्ञात बग / सुविधाओं (सुविधाओं पर चर्चा की जा सकती है; मैं जल्द ही कीड़े ठीक करूंगा):
- यदि डेकोरेटर में पैरामीटर हैं, तो उद्घाटन '(' डेकोरेटर के नाम के समान लाइन पर होना चाहिए;
- कोड संशोधन के कारण, __FUNCTION__ और __METHOD__ अपनी प्रासंगिकता खो देते हैं। अंतिम मूल्यों के साथ लाइनों के लिए स्थिरांक के प्रतिस्थापन को ठीक करना संभव है, लेकिन मैं इस तरह के समाधान की शुद्धता के बारे में सुनिश्चित नहीं हूं;
- __LINE__ हमेशा मैच होना चाहिए, हालांकि डेकोरेटर मापदंडों के बहु-पंक्ति विवरण के मामले में अभी तक काम नहीं किया गया है;
- यदि डेकोरेटर विवरण वाक्यविन्यास त्रुटियों का वर्णन करता है, तो अपवाद को गलत फ़ाइल नाम और रेखा संख्या के साथ अपवाद आधार वर्ग के लिए फेंक दिया जाता है;
- रूसी में github पर कोड में टिप्पणियाँ, के रूप में लिखित अंग्रेजी का मेरा स्तर इतना नहीं है कि जो लिखा है उससे शर्मिंदा न हों। मुझे उम्मीद है, अस्थायी रूप से, और यहां तक कि अगर कोई एक अच्छा अनुवाद के साथ एक प्रतिबद्ध भेजता है, तो यह अच्छा होगा!
- अयोग्य सिंटेक्स पर शपथ आईडीई शपथ। क्या कम से कम शपथ लेने के लिए PHPStorm को प्रशिक्षित करने का कोई तरीका नहीं है?
पुनश्च यदि सर्वेक्षण में "महान विवरणों की आवश्यकता" के पर्याप्त विकल्प हैं, तो मैं इस विस्तार के कार्यान्वयन के बारे में विस्तृत विवरण के साथ एक पोस्ट लिख सकता हूं।