よく組み込みのメソッドで付いてる、
(50).toString();
//=> "50"
みたいなプリミティブ型から繋げられるチェーンを
D, C#, VB.Net, JavaScript, Python
で試してみた。
サンプルプログラム仕様
数値xに対し、buyメソッドを繋げる。
buyメソッドは数値xの値を2倍にして返すものである。
D言語
D言語ではbuy(x)とx.buyが等価であるため、
特別なことは何も行わなくても実装が可能。
import std.stdio;
template buy(T){
int buy(T x){
return cast(int)x*2;
}
}
void main(){
writeln(10.buy.buy);
readln();
}
C#
C#には拡張メソッドと言われる、
疑似的にチェーンメソッドを作成できる仕組みが用意されているのでこれを利用。
using System;
using static System.Console;
static class Program{
static int buy(this object x){
return (int)x*2;
}
static void Main(){
WriteLine(10.buy().buy());
ReadLine();
}
}
VB.Net
C#と同様に拡張メソッドが利用できる。
Option Strict On
Imports System.Console
Module Program
<System.Runtime.CompilerServices.Extension()>
Function buy(x As Object) As Integer
Return CInt(x)*2
End Function
Sub Main()
WriteLine(10.buy.buy)
ReadLine
End Sub
End Module
JavaScript
Numberオブジェクトに直接prototypeを生やすことで可能。
globalオブジェクトに直接手を加えることになるので余り良い手では無さそう。
なお、数値をNumberオブジェクトと認識させるためには括弧で囲む必要がある。
"use strict";
const rl=require("readline").createInterface(process.stdin,process.stdout);
const ReadLine=()=>new Promise(res=>rl.once("line",v=>res(v)));
Number.prototype.buy=function(){
var x=0|this.valueOf();
return 0|x*2;
};
(async function main(){
console.log((10).buy().buy());
await ReadLine()
process.exit();
})()
Python3
素の数値型(int,float)に対してのチェーンを繋げることは不可能っぽい。
クラス自体のオーバーロードや拡張も許されていない様子。
そのため、適当なクラスに数値型を継承してメソッドを拡張させることで疑似的に対応することは可能。
今までint関数だと思っていたけど、これはintオブジェクトのコンストラクタだったということなのかな。
class i_(int):
def buy(self):
return i_(self*2)
if __name__=="__main__":
print(i_(10).buy().buy())
input()
あとがき
rubyとか見てると何でもチェーンしているイメージだったので、
他の言語だとどうなるのか試してみた次第。
意外にやろうと思えばできたけど、
僕は普通に関数使っていればいいのかなぁと思った。
メソッドチェーンカッコいいけど。