ফাংশনগুলি কি তাদের নাম অ্যাক্সেস করতে পারে?


25

সিতে এমন ম্যাজিক ভেরিয়েবল __func__রয়েছে যা বর্তমান ফাংশনটির নাম ধারণ করে। বাশে, FUNCNAMEকলিং স্ট্যাকের সমস্ত ফাংশনের নাম ধারণ করে একটি অ্যারে রয়েছে !!!

ইমাস লিস্পে কি তেমন কিছু আছে? বা কোনও ফাংশনটির নামের অ্যাক্সেসের জন্য কোনও সহজ উপায়?

আমি ইমাস লিসপ ম্যানুয়ালটিতে কোনও উত্তর খুঁজে পাইনি (ভেরিয়েবল এবং ফাংশনের ফাংশন বা সূচী সম্পর্কে 12 অধ্যায় এবং ..)


2
আসলে এর জন্য আপনার কী দরকার?
লুনারিওর

1
এটি হুবহু ম্যাজিক ভেরিয়েবল নয় - এটি কিছু সংকলক দ্বারা প্রসেসর সংজ্ঞা দেওয়া হয়েছে ।
শান অলরেড 21

উত্তর:


6

ইন্টারেক্টিভ ফাংশনগুলির জন্য, অর্থাত্ আদেশগুলি, আপনি পরিবর্তনশীল this-command, বা নিরাপদ, ব্যবহার করতে পারেন real-this-command। পার্থক্যটি হ'ল আপনি যখন নিজের ফাংশনগুলি লিখেন, আপনি স্পষ্টভাবে এর মান পরিবর্তন করতে পারেন this-command। বেশিরভাগ ক্ষেত্রে last-commandকমান্ড পুনরাবৃত্তি সম্পর্কিত কৌশলগুলি খেলতে এটি করা হয় । তুমি (না? পারে) এই সঙ্গে করা উচিত real-this-command। এটি সর্বদা বর্তমান কমান্ডের নাম হবে।

আমি অ-ইন্টারেক্টিভ ফাংশনের সমতুল্য সম্পর্কে সচেতন নই।


3
এটি লক্ষ করা গুরুত্বপূর্ণ this-commandএবং real-last-commandএটি মোটেও পছন্দ নয় __func__। উদাহরণস্বরূপ, যদি কমান্ড A কল কমান্ড বি প্রিন্ট this-commandকরে যা কমান্ড এ প্রিন্ট করবে, বি নয়, এছাড়াও এটি ফাংশনগুলির জন্য মোটেও কাজ করে না।
জর্ডন বিওনদো

1
পছন্দ করেছেন আমি নোট করেছি যে এটি ফাংশন জন্য কাজ করে না। পিএইচএস আমাদের তার প্রসঙ্গ দেয় নি, তাই আমি অনুমান করেছি যে এটি তার অ্যাপ্লিকেশনটির জন্য যথেষ্ট ভাল হতে পারে। আপনার উত্তর আরও মজবুত, কোনও প্রশ্ন নেই।
টাইলার

22

সম্প্রসারণ সময় অনুসন্ধানের সাথে আপডেট উত্তর:

আমি আমার আসল উত্তরে বলেছিলাম যে আরও ভাল পারফরম্যান্স দেওয়ার জন্য রান টাইমের পরিবর্তে প্রসারণ / সংকলন করার সময় এটি করার একটি উপায় থাকতে পারে এবং শেষ পর্যন্ত আমি এই প্রশ্নের উত্তরটি নিয়ে কাজ করার সময় আজ তা প্রয়োগ করেছি: কোন ফাংশনটি ছিল তা আমি কীভাবে নির্ধারণ করতে পারি? স্ট্যাকের মধ্যে ইন্টারেক্টিভভাবে বলা হয়?

এখানে একটি ফাংশন যা সমস্ত বর্তমান ব্যাকট্রেস ফ্রেম দেয়

(defun call-stack ()
  "Return the current call stack frames."
  (let ((frames)
        (frame)
        (index 5))
    (while (setq frame (backtrace-frame index))
      (push frame frames)
      (incf index))
    (remove-if-not 'car frames)))

ম্যাক্রোতে এটি ব্যবহার করে আমরা প্রসারণের স্ট্যাকটি সন্ধান করতে পারি যে সময়ে কোন কার্য সংজ্ঞাটি প্রসারিত হচ্ছে তা দেখতে এবং সেই মানটি কোডের মধ্যে রেখে দেওয়া।

সম্প্রসারণটি করার জন্য এখানে ফাংশনটি দেওয়া হয়েছে:

(defmacro compile-time-function-name ()
  "Get the name of calling function at expansion time."
  (symbol-name
   (cadadr
    (third
     (find-if (lambda (frame) (ignore-errors (equal (car (third frame)) 'defalias)))
              (reverse (call-stack)))))))

এখানে এটি কার্যকর হয়।

(defun my-test-function ()
  (message "This function is named '%s'" (compile-time-function-name)))

(symbol-function 'my-test-function)
;; you can see the function body contains the name, not a lookup
(lambda nil (message "This function is named '%s'" "my-test-function"))

(my-test-function)
;; results in:
"This function is named 'my-test-function'"

আসল উত্তর:

আপনি backtrace-frameস্ট্যাকটি সন্ধান করতে অবধি ব্যবহার করতে পারবেন যতক্ষণ না আপনি ফ্রেম না দেখেন যা সরাসরি ফাংশন কলকে উপস্থাপন করে এবং সেখান থেকে নামটি না পায়।

(defun get-current-func-name ()
  "Get the symbol of the function this function is called from."
  ;; 5 is the magic number that makes us look 
  ;; above this function
  (let* ((index 5)
         (frame (backtrace-frame index)))
    ;; from what I can tell, top level function call frames
    ;; start with t and the second value is the symbol of the function
    (while (not (equal t (first frame)))
      (setq frame (backtrace-frame (incf index))))
    (second frame)))

(defun my-function ()
  ;; here's the call inside my-function
  (when t (progn (or (and (get-current-func-name))))))

(defun my-other-function ()
  ;; we should expect the return value of this function
  ;; to be the return value of my-function which is the
  ;; symbol my-function
  (my-function))

(my-other-function) ;; => 'my-function

এখানে আমি রানটাইমে ফাংশন নেম লুচিংটি করছি যদিও এটি সম্ভবত ম্যাক্রোতে এটি কার্যকর করা সম্ভব যা সরাসরি ফাংশন প্রতীকটিতে প্রসারিত হয় যা পুনরাবৃত্তি কল এবং সংকলিত এলিস্পের জন্য আরও পারফরম্যান্স হতে পারে।

এলিজপের জন্য এক ধরণের ফাংশন কল লগার লেখার চেষ্টা করার সময় আমি এই তথ্যটি পেয়েছি যা এটি এখানে অসম্পূর্ণ আকারে পাওয়া যাবে তবে এটি আপনার পক্ষে কার্যকর হতে পারে। https://github.com/jordonbiondo/call-log


কোডের জন্য ধন্যবাদ। এটি আমার সমস্যা সমাধান করে এবং আমি এটি কয়েক দিনের মধ্যে গ্রহণ করব না যদি না কেউ যদি আমাদেরকে ইঙ্গিত করে এমন ডিবাগারের অংশ হিসাবে কিছু ধরণের "কারেন্ট-ফাংশন-নাম" ভেরিয়েবল না দেয়
phs

যাইহোক, এটি যখন কোনও defunদ্বারা আবদ্ধ থাকে eval-and-compile, অর্থাৎ এটি ফিরে আসে তখন এটি কাজ করে না বলে মনে হয় nil
আলেকজান্ডার শুকায়েভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.