23190


例えば可変長引数を要求する関数が2つあったとして、一方が他方を呼び出す関係にあるとします。

[code]

    (defn abc [& args] (str (first args)))
    (defn aiu [& args] (abc args))
    
[/code]

この場合、REPLで確認できた限りでは以下のようになりました。

[code]

    user=> (abc "a")
    "a"
    user=> (aiu "a")
    "(\"a\")"
    
[/code]

この例でいえば、関数aiuに渡された可変長引数をそのまま可変長引数として関数abcに渡す方法はあるのでしょうか？

何を言いたいのか分かりにくいのかもしれないので、別の例を挙げるとすると、具体的なイメージとしてはrubyのsplat演算子を使った例を思い浮かべています。  
rubyでは引数にアスタリスク(*)をつけると、そこが可変長の引数を表す配列オブジェクトであることを示します。

[code]

    def xyz(*args)
       args.each{|arg| p arg}
    end
    
    xyz(1,2,3)
    => 1
    => 2
    => 3
    
[/code]

この例ではメソッドxyzは可変長の引数を受け取り、個々の引数を表示しています。

そこでclojureの例と同じように別の可変長引数を受け取るメソッドhogeを用意して、その中でxyzを呼び出したとします。

[code]

    def hoge(*args)
       xyz(args)
    end
    
    hoge(1,2,3)
    => [1,2,3]
    
[/code]

見ての通り、clojure同様、可変長引数は一旦配列オブジェクトとしてargsで表現され、それをそのままメソッドxyzに渡すと、配列を1個渡したとみなされます。

この挙動を変え、引数argsを再びxyzに可変長引数として渡すには、xyzに引数としてargsを渡す際にargsの前にアスタリスクをつけます。

[code]

    def foo(*args)
       xyz(*args)
    end
    
    foo 1,2,3
    => 1
    => 2
    => 3
    
[/code]

このような例はrubyでしか知らないのでrubyのコード例を引き合いに出してしまってすみませんが、これと同様に可変長引数をそのまま関数内部で呼び出しているいる別の可変長引数をとる関数に渡したいとき、clojureではどうやったら良いのでしょうか？


CC BY-SA 3.0
2016-03-16T05:40:19.627
23185
2016-03-16T06:44:49.237
9403
question
clojure
clojure で可変長引数をそのまま別の関数に引き渡す方法

[code]

    (def aiu abc)
    
[/code]

とすれば良いと思います。


CC BY-SA 3.0
2016-03-16T06:11:33.353
23187
2016-03-16T06:11:33.353
9575
23185
answer

[code]

    (defn aiu [& args] (apply abc args))
    
[/code]


CC BY-SA 3.0
2016-03-16T06:44:49.237
23190
2016-03-16T06:44:49.237
4010
23185
answer