ইমাকস লেট-বাউন্ড পরামর্শ


14

আমি সাময়িকভাবে কোনও কোডের একটি অংশে একটি ফাংশন ওভাররাইড করতে চাই।

উদাহরণস্বরূপ, নিম্নলিখিতগুলি নিন:

(defun nadvice/load-quiet (args)
  (cl-destructuring-bind
      (file &optional noerror nomessage nosuffix must-suffix)
      args
    (list file noerror t nosuffix must-suffix)))

(defun nadvice/idle-require-quiet (old-fun &rest args)
    (advice-add 'load :filter-args #'nadvice/load-quiet)
    (apply old-fun args)
    (advice-remove #'load #'nadvice/load-quiet))

(advice-add 'idle-require-load-next :around #'nadvice/idle-require-quiet)

কি কাজ করে না:

  • এই. যদি আমি পরামর্শটিকে ম্যানুয়ালি সক্ষম ও নিষ্ক্রিয় করা এড়াতে পারি এবং জিনিসগুলির যত্ন নেওয়ার জন্য ইমাক্সের একক থ্রেডযুক্ত প্রকৃতির উপরে বিশ্বাস করতে পারি তবে এটি আরও পরিষ্কার হবে।
  • cl-letfআমাকে মূল ফাংশনটি উল্লেখ করতে দেবে না, তাই আমি :filter-argsসাধারণত যে জিনিসগুলি করি তা বাস্তবায়ন করতে পারি না।
  • cl-flet অন্যান্য ক্রিয়াকলাপগুলিতে ওভাররাইড করতে পারে না।
  • nofletএটি একটি বাহ্যিক প্যাকেজ, যা আমি এড়াতে চাই। (এছাড়াও আমার প্রয়োজনের চেয়ে অনেক বেশি কাজ করে)

উত্তর:


16

(cl-)letfমূল ফাংশনটি নিজে উল্লেখ করার সময় আপনি কী ব্যবহার করতে পারবেন না ?

এটার মতো কিছু:

;; Original function
(defun my-fun (arg)
  (message "my-fun (%s)" arg))


;; Standard call
(my-fun "arg") ;; => my-fun (arg)


;; Temporary overriding (more or less like an around advice)
(let ((orig-fun (symbol-function 'my-fun)))
  (letf (((symbol-function 'my-fun)
          (lambda (arg)
            ;; filter arguments
            (funcall orig-fun (concat "modified-" arg)))))
    (my-fun "arg")))
;; => my-fun (modified-arg)


;; The overriding was only temporary
(my-fun "arg") ;; => my-fun (arg)



আপনি যদি এটিকে পুনঃব্যবহার করার পরিকল্পনা করেন তবে আপনি এটিকে ম্যাক্রোতেও মোড়াতে পারেন:

(defmacro with-advice (args &rest body)
  (declare (indent 1))
  (let ((fun-name (car args))
        (advice   (cadr args))
        (orig-sym (make-symbol "orig")))
    `(cl-letf* ((,orig-sym  (symbol-function ',fun-name))
                ((symbol-function ',fun-name)
                 (lambda (&rest args)
                   (apply ,advice ,orig-sym args))))
       ,@body)))

উপরের উদাহরণটি নীচের মত আবারও লেখা যেতে পারে:

(defun my-fun (arg)
  (message "my-fun (%s)" arg))


(my-fun "my-arg")

(with-advice (my-fun
              (lambda (orig-fun arg)
                (funcall orig-fun (concat "modified-" arg))))
  (my-fun "my-arg"))

(my-fun "my-arg")

ধন্যবাদ, আমি ঠিক এটিই খুঁজছিলাম আমি শুধু পরিবর্তন চাই ব্যবহার cl-letf*উভয়ের জন্য letগুলি।
— পাইথননট

আমি একটি ম্যাক্রো সংস্করণ যুক্ত করেছি যা letf*উভয় বাইন্ডিংয়ের জন্য কেবল একটি ফর্ম ব্যবহার করে।
— ফ্রানসোয়া ফ্যাভোত্তে

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