人類の役に立たないDSL、そしていつからRubyが最高の言語だと錯覚してた?...

49
人類の役に立たない DSL、そしていつから Rubyが最高の言語だと 錯覚してた? with PHP RubyHiroba 2014 うさみけんた@

Transcript of 人類の役に立たないDSL、そしていつからRubyが最高の言語だと錯覚してた?...

人類の役に立たないDSL、そしていつから

Rubyが最高の言語だと錯覚してた? with PHP

RubyHiroba 2014 うさみけんた@ぞ

お前誰よ

• うさみけんた a.k.a. Zonu.EXE(ぞ)

• Twitter: @tadsan; GitHub: @zonuexe

• %r/たっ?どさん/ と呼ぶと反応します

• 好き: カラオケ、アニメソング、やる夫スレ

• 2012年に脱北して東京にきました

お前誰よ

• プログラム書いてみたいけど書けなかった

• 2010年頃になんとかRubyとJavaScriptおぼえた

• 趣味でやってきたので遊び気分が抜けてない

• 実際に動くサービスを作るよりも、言語の仕様とか処理系で遊んでる方が楽しかった

大学を4年間で卒業できなかったけど、特に就職活動とかしてなかったから札幌のアパートを引き払って実家から大学通って卒業までの単位数を確保しつつ札幌で証明書ベンダーでアルバイトさせてもらってたけど諸々の経緯があり実家に引き込もることになり自宅警備を休業して東京をぷらぷらしたあと某社の紹介で9月から11月の予定で働くことになったけど急に10月いっぱいで引き上げてくれとのことで連絡がきたので、だめもとだったけど後腐れもなく現職の面接を受けて運よく無事に通ってしまったのでPHPの会社に入社したのだけれど社会には闇があることは知れたし特に某社を弾劾する目的ではないので今回は特に触れません。

まあどうでもいいですね

さて

プログラミングは楽しい

コードは書いた通り動いてくれる

構文の自由度が高く高階函数がメソッドの文法に組込まれてる

// JavaScriptの場合 var strToInt = function(v){ return parseInt(v); }; ["1", "2", "3"].map( strToInt ); ["1", "2", "3"].map( function(v){ return parseInt(v); } );

高階函数とは?

// Rubyの場合 str_to_int = ->(v){ v.to_i } ["1", "2", "3"].map( &str_to_int ) ["1", "2", "3"].map{|v| v.to_i }

それが人類の役に立たないコードであっても楽しい

scripter = ->(*args){ ->{ puts args.join("\n") } } title = ->(text) { "『#{text}』\n" } paragraph = ->(*args){ args.join("\n") + "\n" } chara = ->(name) { ->(text){ "#{name}「#{text}」"} } ryu = chara[:リュウ]; tak = chara[:たかし] script = scripter[title[:俺より強い奴に、会いに行く], paragraph[:ピンポーン, ryu[:こんにちは], tak[:はいどなた]], paragraph[ryu[:いまちょっといいですか], tak[:これから出かけます]], paragraph[ryu[:午後出勤ですか?], tak[:はい]], paragraph[ryu[:強そうですね], tak[:なにがですか]], paragraph[ryu[:態度が]], paragraph[:リュウは、自分より強そうな奴に、会いにいったのだった。 完] ] script[]

スクリプト(台本)

『俺より強い奴に、会いに行く』

ピンポーン リュウ「こんにちは」 たかし「はいどなた」

リュウ「いまちょっといいですか」 たかし「これから出かけます」

リュウ「午後出勤ですか?」 たかし「はい」

リュウ「強そうですね」 たかし「なにがですか」

リュウ「態度が」

リュウは、自分より強そうな奴に、会いにいったのだった。 完

台本を出力(実行結果)

フリースタイルで式指向の言語なので、かなり自由な位置に括弧を挿入することができてすごいおもしろい

MatzLisp!

DSLを(比較的)作りやすい(個人の感想)

(予防線を張っておくとrubyも最高の

言語ではなくもっとDSLを作りやすい言語はいろいろある)

さて

プログラミングは楽しい

(いつからRubyが最高のプログラミング言語だと錯覚してた?)

Rails以後の世界でもPHPは平然ととしてでも社会に価値を提供してる

そもそもRubyは最高

なのか?

入門言語としてRubyを手放しで勧められるか

オープンクラスは本当に最高か?

無関係のライブラリが簡単に衝突する

標準クラスがrequireしたライブラリに汚染

される

# ruby # hoge.rb class Hoge … #べんりライブラリ end class Array def hoge # hogeライブラリのべんり処理 end end

Rubyとオープンクラス

# ruby # awesome/array.rb class Array def method_missing name, value # なんかすごい処理をしてくれる end end # awesome.rb require 'awesome/array' array.hoge.each(&:init) #なんか初期化

Rubyとオープンクラス

# ruby require 'hoge' p [1, 2, 3].hoge #=> ちゃんとうごく

require 'awesome' #=> なんかエラーでる

Rubyとオープンクラス

最近はむやみに標準クラスを汚染しないみたいな空気もあるにはあるけど紳士協定にすぎないしrefinementsもあるけ

ど危険を避けられてない

Rubyのメソッドと変数はわかりにくくないか

# ruby foo = "foo"

def foo "FOO" end

p foo

メソッドと変数

同じ名前のローカル変数と メソッドがあると、変数が優先される

メソッドと変数

# python foo = "foo"

def foo(): return "FOO"

print(foo) #=> <function foo at 0x108e6a8c0>

函数は代入文と同じ変数空間 なので、defが上書きする ()をつけないと函数呼び出し ではないので、函数そのものがプリントされる

メソッドと変数

# php $foo = "foo";

function foo() { return "FOO"; }

var_dump($foo); var_dump(foo());

変数には$が必須。 そもそも名前空間が別物なので、衝突しないことは明確。

map

配列の要素におなじ処理を適用したものを返す

高階函数とは?

// Rubyの場合 str_to_int = ->(v){ v.to_i } ["1", "2", "3"].map( &str_to_int ) ["1", "2", "3"].map{|v| v.to_i }

Pythonのmap

# python ary = [[1, 3], [2, 4]] class Foo: @staticmethod def bar(v): return v[0] + v[1] * 10

list(map(Foo.bar, ary))

超わかりやすい!

PHPのmap

# php <?php $ary = [[1, 3], [2, 4]]; trait Foo{ function bar(array $v) { return $v[0] + $v[1] * 10; } } array_map('Foo::bar', $ary));

完全にわかりやすい!!

# ruby ary = [[1, 2], [3, 4]] module Foo def bar(v); v[0] + v[1] * 10; end module_function :bar end p ary.map{|v| Foo.foo(v) } # 短く書くには…? ## たぶん短くならない

Rubyのmap

メソッドの再利用は実は意外にめんどい

PHPにも学びはある

タイプヒント

# php function foo(array $config = []){ … }

foo(1); #=> PHP Catchable fatal error: Argument 1 passed to foo() must be of the type array, string given, called in Command line code on line 1 and defined in Command line code on line 1

クロージャ

# ruby

jojo = ["joseph", "jotaro", "josuke"] is_jojo = ->(name) { return jojo.include?(name) }

クロージャ

# php

$jojo = ["joseph", "jotaro", "josuke"]; $is_jojo = function ($name) use ($jojo) { return in_array($name, $jojo); };

捕捉変数の 明示vs暗黙

どちらが良いかは議論があ

るところ

まとめ

Rubyの設計が手放しで最高であるわけではない点について紹介した

言語設計に王道はなく、それぞれの言語は落としどころを見つけながら現在の仕様に落ち着いてる

使用フォント セプテンバーM・L

IPAex明朝  M+ 1c black

   _    \ヽ, ,、      `''|/ノ       .|  _    |  \`ヽ、|    \, V       `L,,_       |ヽ、)      .|     /           ,、     /        ヽYノ    .|       r''ヽ、.|    |        `ー-ヽ|ヮ     |            `|    ヽ,    ,r      .|      ヽ,r'''ヽ!'-‐'''''ヽ、ノ  ,,,..---r'",r, , 、`ヽ、 ヾ  ヽ、__/ ./ハレハ i`ヽ、 `''r`ミ_    .レ//r,,,、 レ'レハヾ,  L,,_ `ヽ、     "レ, l;;;l   l;;;l`i.リレ' リ ̄~~      ヽ、 ワ `"/-'`'`'        `''''''''"      ┼ヽ  -|r‐、. レ |                  d⌒) ./| _ノ  __ノ