কোলজুরে ডিবাগিং? [বন্ধ]


227

Repl ব্যবহার করার সময় ক্লোজার কোড ডিবাগ করার সর্বোত্তম উপায়গুলি কী?


নীচের উত্তরের সংযোজনগুলি ছাড়াও, আরএপিএল
ভ্যালেন্টিন ওয়েসেলিংক

উত্তর:


158

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

(use 'clojure.contrib.trace)
(defn fib[n] (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2)))))
(dotrace [fib] (fib 3))

আউটপুট উত্পাদন করে:

TRACE t4425: (fib 3)
TRACE t4426: |    (fib 2)
TRACE t4427: |    |    (fib 1)
TRACE t4427: |    |    => 1
TRACE t4428: |    |    (fib 0)
TRACE t4428: |    |    => 0
TRACE t4426: |    => 1
TRACE t4429: |    (fib 1)
TRACE t4429: |    => 1
TRACE t4425: => 2
2

Clojure 1.4 dotraceএ স্থানান্তরিত হয়েছে:

আপনার নির্ভরতা দরকার:

[org.clojure/tools.trace "0.7.9"]
(require 'clojure.tools.trace)

এবং আপনাকে ফাংশন সংজ্ঞাতে ^: গতিশীল যুক্ত করতে হবে

(defn ^:dynamic fib[n] (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2)))))

তারপরে বব আবার আপনার মামা:

(clojure.tools.trace/dotrace [fib] (fib 3))

TRACE t4328: (fib 3)
TRACE t4329: | (fib 2)
TRACE t4330: | | (fib 1)
TRACE t4330: | | => 1
TRACE t4331: | | (fib 0)
TRACE t4331: | | => 0
TRACE t4329: | => 1
TRACE t4332: | (fib 1)
TRACE t4332: | => 1
TRACE t4328: => 2

2
ভাল লাগছে, তবে কীভাবে আপনি 'Clojure.contrib.trace? আমার user=> (use 'closure.contrib.trace) java.io.FileNotFoundException: Could not locate closure/contrib/trace__init.class or closure/contrib/trace.clj on classpath: (NO_SOURCE_FILE:0)
ক্লাসপথে

2
আপনি কি ক্লোজারকে বন্ধ হিসাবে ভুল বানান বানিয়ে বলতে পারেন, বা মন্তব্যতে এটি টাইপো? আপনি কি অন্যান্য ক্লোজার কন্ট্রাইব লাইব্রেরি লোড করতে পারেন?
জন লরেন্স অ্যাসপডেন

12
১.৩ হিসাবে এটি Clojure.tools.trace ( github.com/clojure/tools.trace ) এ চলে গেছে
জর্জ

4
: আপনি পাচ্ছেন এমন: "IllegalStateException ক্যান পরিবর্তনশীল না বেঁধে অ গতিশীল Var" এখানে দেখতে stackoverflow.com/questions/8875353/...
কর্নেলিয়াস

2
এটি 1.5 টি প্রকাশেও কাজ করছে? আমি ক্লোজার কোয়ানদের সাথে ক্লোজার শিখছি, তবে কাজ করার জন্য ডট্রেস পেতে পারি না।
এনহা

100

আমার কাছে কিছুটা ডিবাগিং ম্যাক্রো রয়েছে যা আমি খুব দরকারী বলে মনে করি:

;;debugging parts of expressions
(defmacro dbg[x] `(let [x# ~x] (println "dbg:" '~x "=" x#) x#))

যা চলছে এবং কখন তা দেখতে আপনি যেখানেই এটি সন্নিবেশ করতে পারেন:

;; Examples of dbg
(println (+ (* 2 3) (dbg (* 8 9))))
(println (dbg (println "yo")))
(defn factorial[n] (if (= n 0) 1 (* n (dbg (factorial (dec n))))))
(factorial 8)

(def integers (iterate inc 0))
(def squares  (map #(dbg(* % %))   integers))
(def cubes    (map #(dbg(* %1 %2)) integers squares))
(take 5 cubes)
(take 5 cubes)

মত অনেক clojure.tools.trace/trace
জাজ 21

4
আরও ভাল: স্পাইস্কোপ
জাজ

@ জাজ আমি সম্পূর্ণরূপে একমত। স্পাইস্কোপ দুর্দান্ত! এমনকি কোনও ডিবাগারের চেয়েও ভাল। অবশ্যই টাইপিং জন্য।
জে আতকিন

66

ইমাসসের সিআইডিআর একটি উত্স ডিবাগার পেয়েছে যা আপনি ইম্যাক্স বাফারের ভিতরে প্রকাশের মাধ্যমে অভিব্যক্তিটি পদক্ষেপ করতে পারেন এবং এমনকি নতুন মানগুলি ইনজেক্ট করতে পারেন। আপনি এটি সম্পর্কে এখানে সব পড়তে পারেন । একটি ডেমো স্ক্রিনশট:

সিডির ডিবাগ


46

আমার প্রিয় পদ্ধতিটি printlnসমস্ত কোডে একটি উদার ছিটিয়ে দেওয়া ... এগুলি চালু এবং বন্ধ করা#_ পাঠক ম্যাক্রোর জন্য সহজ ধন্যবাদ (যা পাঠককে নিম্নলিখিত আকারে পড়তে বাধ্য করে, তারপরে এটি কখনও দেখা যায়নি)। অথবা আপনি কোনও ম্যাক্রো প্রসারিত শরীরে প্রসারিত বা nilকোনও বিশেষ ভেরিয়েবলের মানের উপর নির্ভর করে ব্যবহার করতে পারেন , বলুন *debug*:

(defmacro debug-do [& body]
  (when *debug*
    `(do ~@body)))

(def *debug* false)সেখানে একটি সঙ্গে , এটি প্রসারিত হবে nil। এর সাথে trueএটি একটিতে bodyআবৃত হয়ে প্রসারিত হবে do


এই এসও প্রশ্নের গৃহীত উত্তর: অগ্রগতি প্রতিবেদনের জন্য আইডোম্যাটিক ক্লোজার? সিকোয়েন্স অপারেশনগুলি ডিবাগ করার সময় খুব সহায়ক।


এরপর কিছু যা হয় বর্তমানে লম্বাচওড়া কথা-clojure সঙ্গে বেমানান 'র REPL কিন্তু খুব ভাল উল্লেখ করার নয়: debug-repl। আপনি এটি স্ট্যান্ডেলোন রিপ্লেল এ ব্যবহার করতে পারেন যা লেনিনজেন ( lein repl) এর সাথে উদাহরণস্বরূপ পাওয়া সহজ ; এবং যদি আপনি কমান্ড লাইন থেকে আপনার প্রোগ্রামটি চালু করছেন, তবে এটি ঠিক নিজের টার্মিনালে এটির নিজস্ব আরএপিএল আনতে চলেছে। ধারণাটি হ'ল আপনি debug-replম্যাক্রোটিকে আপনার পছন্দ মতো যে কোনও জায়গায় ফেলে দিতে পারেন এবং প্রোগ্রামের প্রয়োগটি সেই স্থানে পৌঁছালে এটির নিজস্ব আরএইপিএল আনতে পারে, সমস্ত স্থানীয় লোকের সাথে এই সম্পর্কিত লিঙ্কের একটি দম্পতি: ক্লোজার ডিবাগ-রিপ্লিজ , ক্লোজার ডিবাগ -রেপল ট্রিকস , কীভাবে ডিবাগ- রেপ্লিট (ক্লোজার গুগল গ্রুপে), ক্লোজারগুলিতে ডিবাগ-রেপ্লিট হয়


ক্লঞ্জার কোডের সাথে কাজ করার সময় স্ল্যামকের বিল্ট-ইন ডিবাগারকে দরকারী করার জন্য সোয়াঙ্ক-ক্লোজার একটি পর্যাপ্ত কাজ করে - লক্ষ্য করুন যে কীভাবে স্ট্যাকট্রেসের অপ্রাসঙ্গিক বিটগুলি গ্রে গ্রেড করা হয়েছে তাই কোডটি ডিবাগ হওয়ার ক্ষেত্রে প্রকৃত সমস্যাটি খুঁজে পাওয়া সহজ। একটি বিষয় মনে রাখবেন যে "নাম ট্যাগ" ছাড়াই বেনাম ফাংশনগুলি স্ট্যাকট্রেসে মূলত তাদের সাথে কোনও কার্যকর তথ্য সংযুক্ত থাকে না; যখন একটি "নাম ট্যাগ" যুক্ত করা হয়, এটি স্ট্যাকট্রেসে প্রদর্শিত হয় এবং সমস্ত কিছু আবার ভাল হয়:

(fn [& args] ...)
vs.
(fn tag [& args] ...)

example stacktrace entries:
1: user$eval__3130$fn__3131.invoke(NO_SOURCE_FILE:1)
vs.                ^^
1: user$eval__3138$tag__3139.invoke(NO_SOURCE_FILE:1)
                   ^^^

5
আসলে ডিবাগ-রেপ্লির একটি সংস্করণ রয়েছে যা এখন দলে দলে কাজ করেছে: hugoduncan.org/post/2010/… ( স্পোলার সতর্কতা: এটি দুর্দান্ত)

1
ঠিক আছে, এবং এখানে একটি লিঙ্ক থাকা ভাল, ধন্যবাদ! দারুণ একমত। :-)
মাইচা মার্কজিক

যদি এটি আপনার স্টাইল হয় তবে আপনি পরবর্তী প্রতিক্রিয়ায় উল্লিখিত ডাবক্স লাইব্রেরি পছন্দ করতে পারেন। github.com/phigskim/debux
ম্যালরি-এরিক

@ ম্যালরি-এরিক ধন্যবাদ, আমি এটি পরীক্ষা করে দেখব!
মাইচা মার্কজিক

37

অ্যালেক্স ওসবার্নdebug-repl ব্যবহার করে আপনি সমস্ত স্থানীয় বাইন্ডিংয়ের সাথে নিজেকে একটি আরএপিএল এ নামানোর জন্য কোড সন্নিবেশ করতে পারেন :

(defmacro local-bindings
  "Produces a map of the names of local bindings to their values."
  []
  (let [symbols (map key @clojure.lang.Compiler/LOCAL_ENV)]
    (zipmap (map (fn [sym] `(quote ~sym)) symbols) symbols)))

(declare *locals*)
(defn eval-with-locals
  "Evals a form with given locals. The locals should be a map of symbols to
values."
  [locals form]
  (binding [*locals* locals]
    (eval
     `(let ~(vec (mapcat #(list % `(*locals* '~%)) (keys locals)))
        ~form))))

(defmacro debug-repl
  "Starts a REPL with the local bindings available."
  []
  `(clojure.main/repl
    :prompt #(print "dr => ")
    :eval (partial eval-with-locals (local-bindings))))

তারপরে এটি ব্যবহার করতে, আপনি যেখানেই Repl শুরু করতে চান সেখানে এটি প্রবেশ করুন:

(defn my-function [a b c]
  (let [d (some-calc)]
    (debug-repl)))

আমি এটি আমার ব্যবহারকারী.এলজে রেখেছি যাতে এটি সমস্ত রিপল সেশনে উপলব্ধ।


16

"Repl ব্যবহার করার সময় ক্লোজার কোডটি ডিবাগ করার সর্বোত্তম উপায়"

সামান্য বাম-ক্ষেত্র, তবে 'রিপল পুনরায় ব্যবহার করুন'

আমি এক বছরেরও বেশি সময় ধরে শখের ক্লোজার লিখছি এবং কোনও ডিবাগিংয়ের সরঞ্জামের বড় প্রয়োজন অনুভব করিনি। আপনি যদি নিজের ফাংশনগুলি ছোট রাখেন, এবং প্রতিটিই প্রত্যাশিত ইনপুটগুলি দিয়ে আরপিএলে চালান এবং ফলাফলগুলি পর্যবেক্ষণ করেন তবে আপনার কোডটি কী আচরণ করছে তার একটি সুন্দর পরিষ্কার চিত্র পাওয়া সম্ভব should

আমি আবিষ্কার করি একটি চলমান অ্যাপ্লিকেশনে স্ট্যাট পর্যবেক্ষণের জন্য একটি ডিবাগার সবচেয়ে দরকারী useful Clojure অপরিবর্তনীয় ডেটা স্ট্রাকচার (কোনও পরিবর্তনযোগ্য রাষ্ট্র নয়) সহ কার্যকরী শৈলীতে লিখতে সহজ (এবং মজাদার) করে তোলে। এটি একটি ডিবাগারের প্রয়োজনকে ব্যাপকভাবে হ্রাস করে। একবার আমি জানতে পারলাম যে সমস্ত উপাদানগুলি আমার প্রত্যাশা অনুযায়ী আচরণ করে (জিনিসগুলির ধরণের দিকে বিশেষ মনোযোগ দেওয়া) তখন বড় আকারের আচরণ খুব কমই সমস্যা হয় is


এটি বেশিরভাগ ক্ষেত্রে সত্য তবে উদাহরণস্বরূপ যখন আপনার একাধিক ফাংশন জুড়ে পুনরাবৃত্তি হয় তখন এটি এত সহজ নয়।
জন

9

আপনি যদি ইমাস / স্লাইম / সোয়াঙ্ক ব্যবহার করেন, তবে REPL এ চেষ্টা করুন:

(defn factorial [n]
        (cond (< n 2) n
              (= n 23) (swank.core/break)
              :else (* n (factorial (dec n)))))

(factorial 30)

এটি আপনাকে এলআইএসপি এর আওতায় নিয়ে যাওয়ার মতো একটি সম্পূর্ণ স্ট্যাক ট্রেস দেয় না, তবে আশেপাশে পোকার জন্য এটি ভাল।

এটি এর সূক্ষ্ম কাজ:

http://hugoduncan.org/post/2010/swank_clojure_gets_a_break_with_the_local_environment.xhtml

যেমন উপরে একটি মন্তব্যে উল্লেখ করা হয়েছিল।


9

ইন্টেলিজিজের জন্য একটি দুর্দান্ত ক্লোজার প্লাগইন রয়েছে যাকে বলা হয় ক্রুসিভ । অন্যান্য জিনিসের মধ্যে এটি একটি আরপিএল সরবরাহ করে যা আপনি ডিবাগ মোডে চালাতে পারেন এবং আপনার ক্লোজার কোডটি দিয়ে যেতে পারেন ঠিক যেমন জাভা হিসাবে।

আমি পিটার ওয়েস্টমাকটের উত্তরটি দ্বিতীয় করব যদিও আমার অভিজ্ঞতায় কেবলমাত্র আমার কোডের টুকরোগুলি আরপিএলে চালানো বেশিরভাগ সময়ই যথেষ্ট পরিমাণে ডিবাগ করার জন্য form


আমি সাফল্যের সাথে লা ক্লজুর ব্যবহার করছিলাম তবে মনে হচ্ছে এখন গিথুব.com
জেটব্রেইনস /

তবে কীভাবে ডিবাগ করবেন Leiningen, এটি দেখায়:Error running 'ring server': Trampoline must be enabled for debugging
গাঙ্ক

এটি নির্দিষ্ট ringবা মনে হয় lein- সম্ভবত একটি পৃথক প্রশ্ন পোস্ট করার উপযুক্ত?
dskrvk

6

২০১ of সাল পর্যন্ত আপনি ক্লাবজুর / স্ক্রিপ্টের জন্য একটি সাধারণ ডিবাগিং লাইব্রেরি ডাবক্স ব্যবহার করতে পারেন যা আপনার Repl পাশাপাশি আপনার ব্রাউজারের কনসোলের সাথে একত্রে কাজ করে। আপনি আপনার কোডে ছিটানো dbg(ডিবাগ) বা clog(কনসোল.লগ) ম্যাক্রোগুলি করতে পারবেন এবং সহজেই আপনার আরপিএল এবং / অথবা কনসোলে মুদ্রিত পৃথক ফাংশনগুলির ফলাফলগুলি পর্যবেক্ষণ করতে পারেন।

প্রকল্পের রেডমি থেকে :

বেসিক ব্যবহার

এটি একটি সহজ উদাহরণ। ম্যাক্রো ডিবিজি একটি মূল ফর্মটি মুদ্রণ করে এবং আরপিএল উইন্ডোতে মূল্যবান মানটি প্রিন্ট করে। তারপরে কোড প্রয়োগের ক্ষেত্রে হস্তক্ষেপ না করে মানটি ফিরিয়ে দেয়।

আপনি যদি ডিবিজি দিয়ে কোডটি এভাবে মুড়ে রাখেন,

(* 2 (dbg (+ 10 20))) ; => 60

নীচে REPL উইন্ডোতে মুদ্রিত করা হবে।

রিপল আউটপুট:

dbg: (+ 10 20) => 30

নেস্টেড ডিবিজি

ডিবিজি ম্যাক্রো নেস্ট করা যায়।

(dbg (* 2 (dbg (+ 10 20)))) ; => 60

রিপল আউটপুট:

`dbg: (+ 10 20) => 30`  

dbg: (* 2 (dbg (+ 10 20))) => 60


5

হুগো ডানকান এবং সহযোগীরা রিটজ প্রকল্পের সাথে আশ্চর্যজনক কাজ চালিয়ে যান । রিটজ-এনআরপিএল একটি এনআরপিএল সার্ভার যা ডিবাগ ক্ষমতা সহ। ওয়াচ হুগো এর Clojure মধ্যে debuggers Clojure / সংযোগমূলক অব্যয় 2012 আলাপ কর্ম এটি দেখতে, ভিডিও স্লাইডের কিছু পাঠযোগ্য নয়, তাই আপনার কাছ থেকে স্লাইড দেখতে চাইতে পারেন এখানে


2

কাস্টম রিডার ম্যাক্রো প্রয়োগ করে এমন স্পাইস্কোপ ব্যবহার করুন যাতে আপনার ডিবাগ কোডটি প্রোডাকশন কোডও হয় https://github.com/dgrnbrg/spyscope


1

জাভা থেকে আগত এবং একটিগ্রহের সাথে পরিচিত হয়ে আমি কাউন্টার ক্লকওয়াইজ (ক্লোজার ডেভেলপমেন্টের জন্য এক্সপ্লিট প্লাগইন) যা অফার করে তা পছন্দ করি: http://doc.ccw-ide.org/docamentation.html#_debug_clojure_code


সঠিক ব্রেকথপয়েন্ট সমর্থন নেই। থ্রেড হত্যা করা কঠিন।
কোডফার্মার

1

জটিল letফর্মগুলি ডিবাগ করার জন্য এখানে একটি দুর্দান্ত ম্যাক্রো রয়েছে:

(defmacro def+
  "def with binding (def+ [{:keys [a b d]} {:a 1 :b 2 :d 3}])"
  [bindings]
  (let [let-expr (macroexpand `(let ~bindings))
        vars (filter #(not (.contains (str %) "__"))
               (map first (partition 2 (second let-expr))))
        def-vars (map (fn [v] `(def ~v ~v)) vars)]
    (concat let-expr def-vars)))

... এবং একটি রচনা এর ব্যবহার ব্যাখ্যা করে


-4

ডিএফ-লেটের ফাংশন সংস্করণ, যা একটি লেটকে ডিফস-এর একটি সিরিজে পরিণত করে। কিছু ক্রেডিট এখানে যায়

(defn def-let [aVec]
  (if-not (even? (count aVec))
    aVec
    (let [aKey (atom "")       
          counter (atom 0)]
      (doseq [item aVec]
        (if (even? @counter) 
          (reset! aKey  item)           
          (intern *ns*  (symbol @aKey)  (eval item)))
        ;   (prn  item)       
    (swap! counter inc)))))

ব্যবহার: উদ্যানের সাথে সামগ্রীটি উদ্ধৃত করার প্রয়োজন, যেমন

(def-let '[a 1 b 2 c (atom 0)])
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.