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


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.