2012-04-23 13 views
18
  • defn =公共
  • defn- =プライベート

おそらく、私の悪いClojureのコーディングスタイルを持っている - しかし、私は見つける私が書く最も機能しますClojureは私が公開したくない小さなヘルパー関数です。デフォルトでは、 Clojureは、DEFN、defn-、パブリック/プライベート、デフォルト

  • によって

    • defn =プライベートとパブリックの何かを作るためには、私はdefn+をしなければならない。

      いくつかの設定オプションは、ありますか?

    ありがとう!

  • 答えて

    16

    番号はありません。

    foo.bar名前空間で使用されるすべてのプライベートヘルパーを含むfoo.bar.internal名前空間を宣言することもできます。これは、マクロ展開でプライベート関数を使用する場合、プライベート関数宣言よりも利点があります。

    +12

    そうではないだけでなく、そのようなコードを見ている他のClojurianの心も本当に混乱します。私はそれが実行可能であってもそれを落胆させるでしょう。 –

    4

    "ヘルパー関数"が一度使用される可能性が高い場合は、より大きな関数のローカルにするか、匿名関数として書き出すかを選択できます。 letfnhttp://clojuredocs.org/clojure_core/clojure.core/letfnおよびhttp://clojuredocs.org/clojure_core/clojure.core/fnを参照してください。

    私はほとんど自分でletfnを使用します。

    +0

    私はこれらのヘルパー関数のサイズが重要ではないと思います。これらが2回以上使用されている場合は、実際に乾燥機コードに抽象化する必要があります。ローカルで使用されていない限り、ローカル/匿名にする理由はわかりません。 – tjb1982

    +0

    これは本当です。私は答えを適応させます。 –

    +0

    私のヘルパーに 'letfn'を使ってみましたが、私のコードが面倒です。だから、少し後に私は 'defn-'に戻った。 –

    4

    @kotarakで述べたように、私が知っている限り、これを行う方法はなく、望ましいことでもありません。私はdefn-を嫌う理由はここに

    は次のとおりです。

    私は様々なClojureのライブラリを使用しているとき、私は時々わずかに良い私の特定のニーズに合わせて一つの機能を変更する必要があることが分かりました。 それはしばしば非常に小さいものであり、それは私の特定のケースでのみ意味があります。多くの場合、これは単なる1文字または2文字です。

    しかし、この関数が内部のプライベート関数を再利用すると、変更が難しくなります。私はそれらのすべてのプライベート関数をコピーして貼り付けなければなりません。

    これは、プログラマが「これは予告なしに変更される可能性がある」と言う方法だと私は理解しています。

    • は常にdefnを使用し、機能が一部あるプログラマに指定するには、すべての公共
    • 使用defn+(それがまだ存在していない)を作る:

      かかわらず、私は反対の大会をしたいと思います彼が使用するはずのパブリックAPI。 defn+は、それ以外の場合はdefnと変わらないはずです。

    はまた、それはとにかくaccess private functionsすることが可能であることに注意してください。

    ;; in namespace user 
    user> (defn- secret [] 
         "TOP SECRET") 
    
    ;; from another namespace 
    (#'user/secret) ;;=> "TOP SECRET" 
    
    +2

    Rubyの経験から、すべてのものに無制限にアクセスできるようになりました(プライベートメソッドには#sendを使用してください)。それは大きな混乱を招き、経験の浅い開発者は本当に悪いことをしてこの "自由"を乱用する傾向があります。 – yagooar

    +0

    大きなclojureコードベースで作業した後、私は実際にプライベート 'defn-'の場合にいくつかの値を見つけました。私はまだ 'defn +'を試してみました。 – nha

    +2

    正確です。私が間違って他の人の機能を変更した場合、それは私のせいです。プログラマとして、内部の変更を阻止することは侮辱です。すべてが公開されるべきです。潜在的な問題を正しく文書化するだけで、プライベートの必要はありません。 – Rebs

    4

    のClojureはLispのであることの美しさ、あなたが構築し、ニーズに合わせて言語を適応させることができるということです。私は非常にあなたがOn Lisp, by Paul Grahamを読むことをお勧めします。彼は今、彼の本を無料でプレゼントします。

    defn +対defn対defn-のあなたの提案について。このサウンドは、自分のマクロを書くための良いケースが好きです。 defnは関数であり、defn-はマクロです。必要に応じて簡単に定義し直すことも、自分でラップすることもできます。

    ここでは、主にClojureの独自の実装(シンプルなユーティリティとテストを含む)に基づいて実装する方法を示します。

    (defmacro defn+ 
        "same as Clojure's defn, yielding public def" 
        [name & decls] 
        (list* `defn (with-meta name (assoc (meta name) :public true)) decls)) 
    
    (defmacro defn 
        "same as Clojure's defn-, yielding non-public def" 
        [name & decls] 
        (list* `defn (with-meta name (assoc (meta name) :private true)) decls)) 
    
    (defn mac1 
        "same as `macroexpand-1`" 
        [form] 
        (. clojure.lang.Compiler (macroexpand1 form))) 
    
    (let [ ex1 (mac1 '(defn f1 [] (println "Hello me."))) 
         ex2 (mac1 '(defn+ f2 [] (println "Hello World!"))) ] 
        (defn f1 [] (println "Hello me.")) 
        (defn+ f2 [] (println "Hello World!")) 
        (prn ex1) (prn (meta #'f1)) (f1) 
        (prn ex2) (prn (meta #'f2)) (f2)) 
    
    関連する問題