Nadvice.el এ যুক্তি তালিকা কীভাবে পরিচালনা করতে হয়?


12

নতুন পরামর্শ ব্যবস্থা সম্পর্কে অন্য প্রশ্নের উত্তর থেকে অনুসরণ করা :

পুরানো শৈলীতে advice.el, কোনও সদস্যদের যাতে এতটা হেরফের না করা হয় সে সম্পর্কে কোনও বক্তব্য না দিয়ে পরামর্শ দেওয়া ফাংশনের যুক্তি তালিকার পৃথক সদস্যদের কৌশলগতভাবে পরিচালনা করা সম্ভব হয়েছিল। উদাহরণস্বরূপ, নিম্নলিখিত পরামর্শ:

(defadvice ansi-term (around prompt-for-name last)
  (let ((name (read-from-minibuffer "Tag: ")))
    (and (not (string= name ""))
         (ad-set-arg 1 (concat "Term: " name)))
    ad-do-it))

একটি ansi-termকলটিতে বাফার-নাম যুক্তির (alচ্ছিক) বিধানের অনুমতি দেয় , ansi-termএখনও তার নিজস্ব ইন্টারেক্টিভ ফর্ম অনুযায়ী অনুরোধ করে তার প্রথম যুক্তিটি অর্জন করবে।

(পরবর্তী রেফারেন্সের জন্য, ansi-termএর স্বাক্ষর রয়েছে (PROGRAM &optional BUFFER-NAME)এবং এর ইন্টারেক্টিভ ফর্মটি বেশ কয়েকটি সম্ভাব্য ডিফল্টের সাথে প্রোগ্রামের জন্য অনুরোধ করে তবে বুফার-NAME সম্পর্কিত কিছুই করে না))

এটি সম্ভব কিনা তা আমি নিশ্চিত নই nadvice.el। যদি এটি হয় তবে আমি কীভাবে এটি সম্পন্ন করতে পারি তা নিশ্চিত। আমি প্রস্তাবিত ফাংশনটির যুক্তি তালিকাটি প্রতিস্থাপনের বেশ কয়েকটি উপায় খুঁজে পেয়েছি ।

উদাহরণস্বরূপ, * তথ্য * (এলিস্প) থেকে পরামর্শ সংযুক্তকারীগুলি :

`:filter-args'
 Call FUNCTION first and use the result (which should be a list) as
 the new arguments to pass to the old function.  More specifically,
 the composition of the two functions behaves like:
      (lambda (&rest r) (apply OLDFUN (funcall FUNCTION r)))

অন্যান্য সংযুক্তকারীগুলি অনুরূপ ক্ষমতা সরবরাহ করে এবং তাদের মধ্যে সাধারণ থ্রেডটি হ'ল যখন কোনও ফাংশনের যুক্তির তালিকাটি প্রতিস্থাপন করা হতে পারে, কাটা হতে পারে, প্রসারিত করা যাবে এবং আল, ততক্ষণ তালিকার প্রদত্ত অবস্থানে যুক্তিটি সংশোধন করার জন্য ফাংশন পরামর্শের কোনও আপাত উপায় নেই without এটি বাকি সম্পর্কে কিছু জোর দেওয়া

আলোচনার ক্ষেত্রে পরামর্শ লেখকের পক্ষে ansi-termকেবলমাত্র একটি বাফার নাম পাস করা অসম্ভব বলে মনে হয় , কারণ একটি তালিকা তৈরি করা সম্ভব নয় যার পজিশন 1 এর মান রয়েছে তবে কিছুই নয়, এমনকি nilপজিশনেও নেই। সাধারণ ক্ষেত্রে, পরামর্শের লেখকের পক্ষে অবস্থান 0 এর বাইরে যুক্তিগুলি নির্বিচারে সংশোধন করা অসম্ভব বলে মনে হয়।

এটি দুর্ভাগ্যজনক বলে মনে হচ্ছে, অনুরূপ প্রভাব তৈরি করার জন্য, কপি-পেস্ট কোডটি প্রয়োজনীয়: বিশেষত, হয় আমি ansi-termইন্টারেক্টিভ ফর্মটি অনুলিপি করতে পারি এবং এটি আমার স্বাদে প্রসারিত করতে পারি, বা আমি ansi-termসম্পূর্ণ অনুলিপি করতে পারি এবং একইভাবে এটি প্রসারিত করতে পারি। উভয় ক্ষেত্রেই, আমার এখন আমার থিম ফাইলটিতে ইমাস লিস্প বিতরণের অংশটি পুনরায় সংজ্ঞায়িত করতে হবে, যা স্থায়িত্ব এবং নান্দনিকতা উভয় ক্ষেত্রেই আমাকে অনাকাঙ্ক্ষিত হিসাবে আঘাত করে।

তাহলে আমার প্রশ্নটি হল: এই ধরণের আর্গুমেন্ট লিস্টের ম্যাঙ্গলিংয়ের মাধ্যমে কি কাজ করা যেতে পারে nadvice.el? যদি তাই হয়, কিভাবে?


3
কেন আপনি আপনার নিজের ইন্টারেক্টিভ কমান্ডটিকে অ্যানসি-টার্মের শীর্ষে সংজ্ঞায়িত করেন না? আমি মনে করি এটি এখানে পছন্দসই সমাধান।
লুনারিওর

1
অবশ্যই আমাকে তা করতে বাধা দেওয়ার কিছু নেই, তবে এটি দশকের দশকের মূল্যমানের পেশী স্মৃতিশক্তির আরও ভাল অংশের পরিবর্তনের প্রয়োজন, যা আমি পারলে এড়াতে চাই।
অ্যারন মিলার

উত্তর:


5

এটি দুর্ভাগ্যজনক বলে মনে হচ্ছে, অনুরূপ প্রভাব তৈরি করার জন্য, কোডটি অনুলিপি করা দরকার: [...] আমি ansi-termএর ইন্টারেক্টিভ ফর্মটি অনুলিপি করতে পারি

বিপরীতে, আমি মনে করি পরামর্শ দেওয়া ফাংশনের ইন্টারেক্টিভ ফর্মটি অনুলিপি করা ভাল ধারণা হবে, যদিও আপনাকে এখানে আসলে এখানে করতে হবে না।

আমি আপনাকে উপর থেকে নীচে প্রশ্ন পড়েছি। কোড-ব্লকে পৌঁছে আমি অনুমান করেছিলাম যে আপনার পরামর্শ সম্ভবত বাফারের নাম পরিবর্তন করছে। আপনি পরে মন্তব্য হিসাবে স্বাক্ষর প্রদান না করা পর্যন্ত আমি জানতাম না ।

আলোচনার ক্ষেত্রে, পরামর্শ লেখকের পক্ষে ansi-termকেবল বাফারের নাম পাস করা অসম্ভব বলে মনে হচ্ছে , কারণ এমন একটি তালিকা তৈরি করা সম্ভব নয় যার পজিশন 1 এর মান রয়েছে তবে কিছুই নয়, এমনকি nilপজিশনে 0 নেই।

আসলে কিছুই কিছুই কম কিছু নয়। :-) তবে এখানে খুব কমই প্রাসঙ্গিক।

আপনি উদ্ধৃত দস্তাবেজগুলিতে যেমন দেখতে পাচ্ছেন, পরামর্শ অনুসারে প্রত্যাবর্তিত মানটি প্রস্তাবিত ফাংশনের আর্গুমেন্ট হিসাবে ব্যবহৃত হয়। রিটার্ন মানটি কেবল পরিবর্তিত হয়েছে এমনগুলি নয় বরং সমস্ত আর্গুমেন্টের একটি তালিকা হতে হবে।

পুরানো পরামর্শ যতটা সম্ভব কাছাকাছি থাকা, এটি ব্যবহার করে আপনার যা করতে হবে তা হল nadvice:

(defun ansi-term--tag-buffer (args)
  ;; As npostavs pointed out we also have to make sure the list is
  ;; two elements long.  Which makes this approach even more undesirable.
  (when (= (length args) 1)
    (setq args (nconc args (list nil))))
  (let ((name (read-from-minibuffer "Tag: ")))
    (and (not (string= name ""))
         (setf (nth 1 args) (concat "Term: " name))))
  args)

(advice-add 'ansi-term :filter-args 'ansi-term--tag-buffer)

তবে আমি আপনাকে পরামর্শটি পরিবর্তে এর মতো সংজ্ঞায়িত করার পরামর্শ দিচ্ছি:

(defun ansi-term--tag-buffer (program &optional buffer-name)
  (list program
        (let ((tag (read-from-minibuffer "Tag: ")))
          (if (string= tag "")
              buffer-name
            (concat "Term: " tag)))))

এই রূপটি আসলে স্ব-ব্যাখ্যামূলক।


1 ম ভেরিয়েন্টের জন্য আপনাকে argsকলটির মতো তালিকার তালিকাকে প্রসারিত করতে হবে (ansi-term "foo"), অন্যথায় (setf (nth 1 args)...ত্রুটি বাড়িয়ে তুলবে।
npostavs

হ্যাঁ আপনি ঠিক. দ্বিতীয় বৈকল্পিকটি ব্যবহারের আর একটি কারণ - প্রথমটিতে একটি বাগ রয়েছে ;-) বিক্ষোভের উদ্দেশ্যে, কেবল buffer-nameএটি বাধ্যতামূলক বলে ধরে নিন ।
তারসিয়াস

"বিপরীতে, আমি মনে করি পরামর্শ দেওয়া ফাংশনের ইন্টারেক্টিভ ফর্মটি অনুলিপি করা ভাল ধারণা হবে" - কেন তাই? অনুলিপি-পেস্টিং কোড অন্য প্রতিটি ক্ষেত্রে একটি খারাপ ধারণা; কেন এখানে না?
অ্যারন মিলার 23

আসলে আমি মনে করি না যে "কপি-পেস্ট" এই ক্ষেত্রে সঠিক শব্দ, আমি কেবল এটি ব্যবহার করেছি কারণ আপনি করেছিলেন। তবে এখানে যদি এই শব্দটি ব্যবহার করা যথাযথ হয় তবে "কপি-পেস্ট করবেন না" এটি কেবল একটি পরম নিয়ম নয় ur অন্যান্য হিউরিস্টিকস, যা আমি এখানে প্রয়োগ করি বলে মনে করে তা হ'ল "ভেরিয়েবল এবং যুক্তিগুলিকে অর্থবোধক নাম দিন" এবং "আপনার যখন কোনও কিছু জটিল করার জন্য বা ভার্বোজ হওয়ার মধ্যে কোনও পছন্দ থাকে, তখন ভার্জোজ দিয়ে যান"।
তারসিয়াস

1
উম, আসলে, এই এখনও নষ্ট হয়ে গেছে, :filter-argsপরামর্শ একটি পায় একক যুক্তি যা পরামর্শ ফাংশন args একটি তালিকা রয়েছে, তাই 1 ম বৈকল্পিক ড্রপ উচিত &restএবং 2nd বৈকল্পিক ডেসট্রাকচারিং কনস্ট্রাক্ট কিছু বাছাই ব্যবহার করতে চমৎকার নাম পেতে হবে।
npostavs

3

আমি এটি কীভাবে করব তা এখানে:

(defun my-ansi-term-prompt-for-name (orig-fun program
                                     &optional buffer-name &rest args)
  (apply orig-fun program
         (or buffer-name
             (let ((name (read-string "Tag: ")))
               (and (> (length name) 0)
                    (concat "Term: " name))))
         args))
(advice-add 'ansi-term :around #'my-ansi-term-prompt-for-name)

:filter-argsআমি ব্যক্তিগতভাবে এটিকে পরিচয় করিয়ে দেওয়ার সময় এটি খুব কমই সুবিধাজনক বলে মনে করি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.