সম্পাদনা : সাম্প্রতিক ইমাসকে এটি করার আরও ভাল উপায় হ'ল আর্গুমেন্টের সংখ্যা পরীক্ষা করার জন্য একটি সংকলক ম্যাক্রো সংজ্ঞায়িত করা । একটি সাধারণ ম্যাক্রো ব্যবহার করে আমার মূল উত্তরটি নীচে সংরক্ষণ করা হয়েছে, তবে একটি সংকলক-ম্যাক্রো উচ্চতর কারণ এটি ফাংশনে funcall
বা apply
রানটাইমে পাস করা বাধা দেয় না ।
ইমাক্সের সাম্প্রতিক সংস্করণগুলিতে, আপনি আপনার ফাংশনের জন্য একটি সংকলক-ম্যাক্রো সংজ্ঞায়িত করে এটি করতে পারেন যা আর্গুমেন্টের সংখ্যাটি পরীক্ষা করে এবং এটি মেলে না তবে একটি সতর্কতা (বা এমনকি একটি ত্রুটি) তৈরি করে। একমাত্র সূক্ষ্মতা হ'ল মূল্যায়ন বা সংকলনের জন্য সংকলক ম্যাক্রোর মূল ফাংশন কল ফর্মটি অপরিবর্তিত করা উচিত। এটি একটি &whole
আর্গুমেন্ট ব্যবহার করে এবং এর মান ফিরিয়ে নেওয়া হয়। এটি এইভাবে সম্পাদন করা যেতে পারে:
(require 'cl-lib)
(defun my-caller (&rest args)
(while args
(message "%S %S" (pop args) (pop args))))
(define-compiler-macro my-caller (&whole form &rest args)
(when (not (cl-evenp (length args)))
(byte-compile-warn "`my-caller' requires an even number of arguments"))
form)
(my-caller 1 2 3 4)
(my-caller 1 2)
(funcall #'my-caller 1 2 3 4) ; ok
(apply #'my-caller '(1 2)) ; also ok
(my-caller 1) ; produces a warning
(funcall #'my-caller 1 2 3) ; no warning!
(apply #'my-caller '(1 2 3)) ; also no warning
নোট করুন funcall
এবং apply
এখন ব্যবহার করা যেতে পারে, তবে তারা সংকলক ম্যাক্রোর দ্বারা তর্ক তদন্তকে বাইপাস করে। তাদের নাম সত্ত্বেও, কম্পাইলার ম্যাক্রো এছাড়াও মূল্যায়ন 'ব্যাখ্যা' অবশ্যই মাধ্যমে প্রসারিত হবে বলে মনে হচ্ছে C-xC-e, M-xeval-buffer, তাই আপনি মূল্যায়ন পাশাপাশি এই উদাহরণে সংকলন ত্রুটি পাবেন।
আসল উত্তর অনুসরণ:
আপনি "ম্যাক্রো ব্যবহারের জন্য যা সম্প্রসারণের সময় সতর্কতা সরবরাহ করবে" এর পরামর্শের জন্য জর্ডনের পরামর্শটি কীভাবে কার্যকর করতে পারেন তা এখানে রয়েছে। এটি খুব সহজ হতে দেখা যাচ্ছে:
(require 'cl-lib)
(defmacro my-caller (&rest args)
(if (cl-evenp (length args))
`(my-caller--function ,@args)
(error "Function `my-caller' requires an even number of arguments")))
(defun my-caller--function (&rest args)
;; function body goes here
args)
(my-caller 1 2 3 4)
(my-caller 1 2 3)
একটি ফাইলের উপরেরটি সংকলন করার চেষ্টা ব্যর্থ হবে (কোনও .elc
ফাইল তৈরি করা হয় না), সংকলন লগে একটি দুর্দান্ত ক্লিকযোগ্য ত্রুটি বার্তা সহ উল্লেখ করে:
test.el:14:1:Error: `my-caller' requires an even number of arguments
এছাড়াও আপনি প্রতিস্থাপন করতে পারে (error …)
সঙ্গে (byte-compile-warn …)
একটি ত্রুটির পরিবর্তে একটি সতর্কবার্তা উত্পাদন করতে, চালিয়ে যেতে সংকলন অনুমতি দেয়। (মন্তব্যগুলিতে এটিকে নির্দেশ করার জন্য জর্ডনকে ধন্যবাদ)।
সংকলনের সময়ে ম্যাক্রোগুলি প্রসারিত হওয়ায় এই চেকটির সাথে কোনও রান-টাইম জরিমানা যুক্ত নেই। অবশ্যই, আপনি অন্য লোককে my-caller--function
সরাসরি কল করা বন্ধ করতে পারবেন না তবে আপনি কমপক্ষে ডাবল হাইফেন কনভেনশনটি ব্যবহার করে এটি একটি "ব্যক্তিগত" ফাংশন হিসাবে বিজ্ঞাপন করতে পারেন।
এই উদ্দেশ্যে ম্যাক্রো ব্যবহারের একটি উল্লেখযোগ্য অসুবিধা হ'ল এটি my-caller
এখন প্রথম শ্রেণির ফাংশন নয়: আপনি এটিকে funcall
বা apply
রানটাইমে পাস করতে পারবেন না (বা কমপক্ষে এটি আপনার প্রত্যাশা অনুযায়ী করবে না)। এই সম্মানের ক্ষেত্রে, এই সমাধানটি কেবল কোনও আসল ফাংশনটির জন্য কেবল একটি সংকলক সতর্কতা ঘোষণা করতে সক্ষম হওয়ার মতো যথেষ্ট ভাল নয়। অবশ্যই, ব্যবহারটি apply
যে কোনও উপায়ে সংকলন সময়ে ফাংশনটিতে কতগুলি আর্গুমেন্ট পাস হচ্ছে তা যাচাই করা অসম্ভব করে তোলে, তাই সম্ভবত এটি একটি গ্রহণযোগ্য বাণিজ্য-বন্ধ।