আপনি যা চান তা করার জন্য একটি ম্যাক্রো
বাছাইয়ের অনুশীলন হিসাবে:
(defmacro setq-every (value &rest vars)
"Set every variable from VARS to value VALUE."
`(progn ,@(mapcar (lambda (x) (list 'setq x value)) vars)))
এখন এটি চেষ্টা করুন:
(setq-every "/foo/bar" f-loc1 f-loc2)
এটা কিভাবে কাজ করে
যেহেতু লোকেরা আগ্রহী এটি কীভাবে কাজ করে (মন্তব্য অনুযায়ী), তাই এখানে একটি ব্যাখ্যা। ম্যাক্রোগুলি কীভাবে লিখতে হয় তা শিখতে একটি ভাল কমন লিস্প বইটি বেছে নিন (হ্যাঁ, কমন লিস্প, আপনি ইমাস লিস্পে একই জিনিস করতে সক্ষম হবেন, তবে সাধারণ লিস্প কিছুটা শক্তিশালী এবং আরও ভাল বই রয়েছে, আইএমএইচও)।
ম্যাক্রোগুলি কাঁচা কোডে কাজ করে। ম্যাক্রো তাদের আর্গুমেন্টগুলি মূল্যায়িত করে না (কার্যগুলি ভিন্ন)। সুতরাং আমরা এখানে মূল্যহীন value
এবং সংগ্রহ করেছি vars
, যা আমাদের ম্যাক্রোর জন্য কেবল প্রতীক are
progn
setq
এক মধ্যে বিভিন্ন ফর্ম গ্রুপ । এই জিনিস:
(mapcar (lambda (x) (list 'setq x value)) vars)
কেবলমাত্র setq
ফর্মের একটি তালিকা তৈরি করে, ওপি'র উদাহরণ ব্যবহার করে এটি হবে:
((setq f-loc1 "/foo/bar") (setq f-loc2 "/foo/bar"))
আপনি দেখুন, ফর্ম ভিতরে backquote ফর্মের এবং একটি কমা দিয়ে পূর্বনির্ধারিত
,
। ব্যাককোটিড ফর্মের ভিতরে সমস্ত কিছু সাধারণত হিসাবে উদ্ধৃত হয়, তবে ,
অস্থায়ীভাবে " টার্ন অন" মূল্যায়ন হয়, সুতরাং পুরোটি ম্যাক্রোএক্সপেনশন mapcar
সময়ে মূল্যায়ন করা হয়।
অবশেষে s এর @
তালিকা থেকে বাহ্যিক বন্ধনী সরিয়ে দেয় setq
, তাই আমরা পাই:
(progn
(setq f-loc1 "/foo/bar")
(setq f-loc2 "/foo/bar"))
ম্যাক্রোস নির্বিচারে আপনার উত্স কোডটি রূপান্তর করতে পারে, এটি দুর্দান্ত না?
একটি সতর্কীকরণ
এখানে একটি ছোট সতর্কতা, প্রথম যুক্তিটি কয়েকবার মূল্যায়ন করা হবে, কারণ এই ম্যাক্রো মূলত নিম্নলিখিতটিতে প্রসারিত:
(progn
(setq f-loc1 "/foo/bar")
(setq f-loc2 "/foo/bar"))
আপনি দেখতে পাচ্ছেন, এখানে যদি আপনার কোনও ভেরিয়েবল বা স্ট্রিং থাকে তবে তা ঠিক আছে, তবে আপনি যদি এই জাতীয় কিছু লিখে থাকেন:
(setq-every (my-function-with-side-effects) f-loc1 f-loc2)
তারপরে আপনার ফাংশনটি একাধিকবার কল করা হবে। এটি অনাকাঙ্ক্ষিত হতে পারে। once-only
( এমএমটি প্যাকেজে উপলব্ধ
) এর সাহায্যে এটি কীভাবে ঠিক করা যায় তা এখানে :
(defmacro setq-every (value &rest vars)
"Set every variable from VARS to value VALUE.
VALUE is only evaluated once."
(mmt-once-only (value)
`(progn ,@(mapcar (lambda (x) (list 'setq x value)) vars))))
আর সমস্যাটা চলে গেছে।