23571


`clojure`初心者です。

今日ようやく`defrecord`のことを初めて知りました。深いことまでは分かりませんが、ふと思ったことがあります。  
`Java`であっても`toString`メソッドがクラスに定義されていればそのクラスオブジェクトに合った文字列表現を返すことができるように、`clojure`の場合も似たような仕組みはあるのでしょうか？

興味半分に`defrecord`で定義したデータ型を`str`関数に渡すと何かハッシュ値のようなものが出てきました。

[code]

    user=> (defrecord abc [aiu xyz])
    user.abc
    user=> (->abc 123 "ABC")
    #user.abc{:aiu 123, :xyz "ABC"}
    user=> (str (->abc 123 "ABC"))
    "user.abc@79b2cefe"
    
[/code]

この最後の部分を例えば`"[abc: 123
xyz]"`のような文字列表現に変えることはできるのでしょうか。もしかするとそんなことをしたら`clojure`の動作を破壊してしまうのかもしれませんが……

`defrecord`ではない、ごく単純な例だとデータの内容がわかりやすく文字列化されているようです。

[code]

    user=> (str #{1 2 3})
    "#{1 3 2}"
    
[/code]

`ruby`などではこの手の方法をデバッグで有効に使うこともあったので質問してみました。  
今これがわからなくて困っているわけではないですが、後々のプログラミングで気になるようにも思うので、ご教示いただけると嬉しいです。よろしくお願いします。

※ubuntu 15.04/windows7で、Clojure 1.8を使っています。


CC BY-SA 3.0
2016-03-28T08:18:10.137
23536
2016-03-29T04:26:13.163
2016-03-28T09:52:15.047
9403
9403
question
clojure
defrecordで定義したデータを文字列化したときの内容はカスタマイズできるのでしょうか


質問のタイトルとズレはしますが、質問の意図からすると pr-str を使えば解決できる問題だと思います。また、シリアライズした結果を標準出力に出力する
prn という関数もあります。

本当に望むのであれば次のような書き方もできます(が、多くの場合必要ないですし、推奨はしません)。

[code]

    (defrecord Member [name age]
      java.lang.Object
      (toString [_]
        (pr-str [name age])))
    
    (str (map->Member {:name "Mike" :age 10}))
    ;; -> "[\"Mike\" 10]"
    
[/code]


CC BY-SA 3.0
2016-03-28T21:58:12.557
23571
2016-03-28T23:10:34.930
2016-03-28T23:10:34.930
9525
9525
23536
answer


わかりやすく文字化するというと、ayato_pさんの書かれているように`pr-
str`ですね。REPLや`println`などの表示と同じ形式（質問内でいうと`#user.abc{:aiu 123, :xyz
"ABC"}`）です。このへんは、Rubyでいうと`inspect`や`p`あたりのポジションでしょうか。

で、その`pr-str`やREPLなどの形式をカスタマイズするにはマルチメソッドの`print-method`を定義します。

[code]

    user=> (defrecord abc [aiu xyz])
    user.abc
    user=> (defmethod print-method abc [x ^java.io.Writer w]
      #_=>   (.write w (str "{{" (:aiu x) ", " (:xyz x) "}}")) )
    #object[clojure.lang.MultiFn 0x76c1ccae "clojure.lang.MultiFn@76c1ccae"]
    user=> (abc. 123 "ABC")
    {{123, ABC}}
    
[/code]

> もしかするとそんなことをしたらclojureの動作を破壊してしまうのかもしれませんが……

Clojureのprint系関数の出力形式は、そのままreadできるものとされています。懸念としてはそのへんの整合性があります。


CC BY-SA 3.0
2016-03-29T04:26:13.163
23584
2016-03-29T04:26:13.163
4010
23536
answer