説教臭いブログ

中途半端なので、タイトル変えてみた。多分説教臭いと思う。

言語別 duck typing してみた。

最近 golang 書いてるけど、ちょっと独特なメソッドのレシーバーの指定の仕方だったりしてなんとなく比較を書いてみる duck typing といえば、Rubyが代名詞的な感じがあるけど他の言語でも普通にできたりする。Rubyほど「意識して」使われない気もするし、JavaScriptとかではそもそもクラスが無いのでそれが普通だったりする。


そもそも duck typing とは

「ダック・タイピング」。一応。

ダック・タイピング - Wikipedia

アヒルのように鳴くならアヒルとみなす、みたいな感じ。Rubyだと型が無いので、特定のメソッドがあって呼び出しできるなら中身が何でもいいよね、みたいな感じだろうか。雑だけど

例えば、 call() というメソッドがあって戻り値が string だったら〜〜機能として実行できる、とかそういう感じになる。(説明は割愛:Rubyの記事とか探して読むと良さそう)

最初から色々メソッド(関数)を実装しておかなくても、好きなタイミングでメソッドを生やしたりして機能を追加できるよ、みたいな感じで使われたりする。

各言語での実装例

Ruby

メジャーどころ

msg = "婚活デカみてる。"

def msg.sudden
  <<-FMT
  _人人人人人人人人人人_
  > #{self} <
   ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄
  FMT
end

puts msg.sudden

String でもなんでもイケる。なんでもかんでもできすぎる感もあり、多用すると危ない。 特に、↑みたいに String クラスに生やすのは、影響を完全に把握してないとやばい

JavaScript

これは特別な感じではないので、いちいち気にして使わない

var msg = {};
msg.str = "婚活デカみてる。";

msg.sudden = function() {
  return "_人人人人人人人人人人_\n"+
    "> "+this.str+" <\n"+
    " ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄";
};

console.log(msg.sudden());

Coffee Stript

JS書いたしおまけ

msg = {}
msg.str = "婚活デカみてる。"

msg.sudden = ()->
  """
  _人人人人人人人人人人_
  > #{this.str} <
   ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄
  """

console.log msg.sudden()

golang

主題。これも別に特殊さは無いけど、他の言語から見るとちょっと考え方が変わってる感じする。

package main

import "fmt"

type MyString struct {
  Str string
}

func main() {
  msg := MyString{"婚活デカみてる。"}
  fmt.Println(msg.sudden())
}

func (s MyString) sudden() string {
  return fmt.Sprintf(`_人人人人人人人人人人_
> %s <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄`, s.Str)
}

string 型には直接functionを生やすことができないけど、自分で宣言した type(というのか struct というのか)に生やす感じになる。

func宣言で 「レシーバー」「関数名」「引数」「戻り値(複数戻り値があるときはカッコで括って複数書く)」という感じで並ぶ。C言語の系統での宣言とはちょっと並びが違うので「お?」ってなる。けどこれはすぐに慣れる。 (Rubyのヒアドキュメントでインデントできる、という仕組みがなんかいいな、と思う)

実行結果

_人人人人人人人人人人_
> 婚活デカみてる。 <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄

おまけ

php

duck typing はできない。

<?php
$msg = "婚活デカみてる。";

function sudden($s) {
  return <<<FMT
  _人人人人人人人人人人_
  > {$s} <
   ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄
FMT;
}

echo sudden($msg);

※ 完全に蛇足。諸事情あって、PHPはそんなに詳しくないけど。


golang のかるーいネタ書きたかっただけなので、大して意味ない。