Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Learn Ruby from One

kyoendo
September 02, 2012

Learn Ruby from One

kyoendo

September 02, 2012
Tweet

Other Decks in Programming

Transcript

  1. 1から始めるRuby kyoendo(a.k.a melborne) http://melborne.github.com

  2. 数学の世界で1は数である

  3. 3歳の⼦供でもそれを知っている

  4. そして 私やあなたが⽼いて死にゆくまで

  5. 1は数であり そこに疑念の⼊る余地はない

  6. プログラミングの世界でも ふつう1は数である

  7. CでもJavaでもHaskellでも 1は数であり

  8. それ以上でも それ以下でもない

  9. ところが驚くべきことに

  10. Rubyの世界では

  11. 1は数ではないのである

  12. 嘘だと思うなら irbを⽴ち上げて 次のようにしてみるといい

  13. $ irb $ 1.next # => 2

  14. あなたは今1に "next" というメッセージを送った

  15. そうしたら1は 2という答えを返したのだ

  16. つまりRubyの世界で1は 数以上のものであり

  17. メッセージに返答する 「何か」である

  18. Rubyの世界でそれは 「オブジェクト」 と呼ばれている

  19. 1はメッセージに反応する オブジェクトである

  20. しかしここで⼀つの疑問が湧いてくる

  21. それならば今 1が返した2というのは 何なのか

  22. 数なのか それとも オブジェクトなのか

  23. この疑問にもirbが答えてくれる

  24. $ irb $ 1.next.next # => 3

  25. 1からの返答にさらに "next"という メッセージを送ってみる

  26. つまり "1.next"で返される2に メッセージを送ってみると

  27. 果たして 3が返ってきた

  28. そう1から返答された2も やはりオブジェクトだったのだ

  29. 疑い深いあなたは これだけでは 納得しないかも知れない

  30. そしてirbできっと 次のように ⼊⼒するのだろう..

  31. $ irb $ 1.next.next.next.next.next.next.next.next.next.next \ .next.next.next.next.next.next.next.next.next.next \ .next.next.next.next.next.next.next.next.next.next \ .next.next.next.next.next.next.next.next.next.next

    \ .next.next.next.next.next.next.next.next.next.next \ .next.next.next.next.next.next.next.next.next.next \ .next.next.next.next.next.next.next.next.next.next \ .next.next.next.next.next.next.next.next.next.next \ .next.next.next.next.next.next.next.next.next.next \ .next.next.next.next.next.next.next.next.next # => 100
  32. 納得した?

  33. そう Rubyの世界では ⼊り⼝も出⼝も

  34. そのすべてが オブジェクトなのである

  35. さて 1がオブジェクトなら "next"以外の

  36. どんなメッセージに 反応するのかが 気になるところだ

  37. Rubyではその答えも 1に聞けばいい

  38. "methods" というメッセージを 1に送ってみよう

  39. $ irb $ 1.methods $ => [:to_s, :[email protected], :+, :-,

    :*, :/, :em, :%, :modulo, :divmod,\ :fdiv, :**, :abs, :magnitude, :==, :===, :<=>, :>, :>=, :<,\ :<=, :~, :&, :|, :^, :[], :<<, :>>, :to_f, :size, :zero?,\ :odd?, :even?, :succ, :integer?, :upto, :downto, :times,\ :next, :pred, :chr, :ord, :to_i, :to_int, :floor, :ceil,\ :truncate, :round, :gcd, :lcm, :gcdlcm, :numerator,\ :denominator, :to_r, :rationalize, :singleton_method_added,\ :coerce, :i, :[email protected], :eql?, :quo, :remainder, :real?,\ :nonzero?, :step, :to_c, :real, :imaginary, :imag, :abs2,\ :arg, :angle, :phase, :rectangular, :rect, :polar,\ :conjugate, :conj, :between?, :nil?, :=~, :!~, :hash,\ :class, :singleton_class, :clone, :dup, :initialize_dup,\ :initialize_clone, :taint, :tainted?, :untaint, :untrust,\ :untrusted?, :trust, :freeze, :frozen?, :inspect, :methods,\ :singleton_methods, :protected_methods, :private_methods,\ :public_methods, :instance_variables,\ :instance_variable_get, :instance_variable_set,\ :instance_variable_defined?, :instance_of?, :kind_of?,\ :is_a?, :tap, :send, :public_send, :respond_to?,\ :respond_to_missing?, :extend, :display, :method,\ :public_method, :define_singleton_method, :__id__,\ :object_id, :to_enum, :enum_for, :equal?, :!, :!=,\ :instance_eval, :instance_exec, :__send__]
  40. これらは 1が応答できる メッセージの集合で

  41. Rubyでは 「メソッド」 と呼ばれている

  42. つまり1は あなたからの問い合わせに対し これら130個もの メソッドで応答する

  43. Rubyのクラス

  44. 上の説明を聞いて あなたは

  45. 「Rubyの1って天才、スゲー」 とつぶやいたに違いない

  46. しかし事実はそうではない

  47. 実は1の中⾝は 私やあなたのあたまの中同様

  48. ほとんど空っぽなのである

  49. 空っぽなのに1は これらのメッセージに 反応できるのである

  50. このカラクリは難しいものではない

  51. Rubyにおいて1は 先のメソッドの集合を 実際に持っているFixnumという クラスにリンクされている

  52. そして1があなたからの メッセージを受け取ると それをFixnumに渡して

  53. その返答が得られたら 1はそれをあなたに 返しているだけなのだ

  54. つまり1は 「ググって」ばかりの 私やあなたと同じで

  55. 問い合わせのたびにただ 「クラスってる」だけで

  56. Fixnumこそが Google同様の スゲー存在なのである

  57. そして私やあなたは Webの世界では Rubyの1みたいな 存在なのである..

  58. Ruby設計者が このような仕組みを採⽤した理由は 容易に想像がつくだろう

  59. そうRubyでは 2も3も109も17320508も Fixnumというクラスに リンクしていて

  60. これらの数に対する 問い合わせがあったときには すべてFixnumが 答えを⽤意しているのだ

  61. そうすればこれらの数が それぞれ個別に 130個のメソッドを持つ 必要はなくなる

  62. メソッド定義

  63. Rubyで 「プログラミングをする」 というのは

  64. 「オブジェクトにメッセージを送る」 とほぼ同義である

  65. ⾃由で柔軟な プログラミングを 実現するため

  66. Rubyの設計者は ⼤量の メソッドを⽤意した

  67. しかし もちろんそれだけでは 真に⾃由なプログラミングが できるわけではない

  68. 独⾃メソッドが 定義できてこそ 本当のプログラミングが 実現できる

  69. そしてRubyは それをあなたに許す

  70. 今あなたが 1に挨拶したら 返事がほしいとしよう

  71. 1の中⾝は空っぽで Fixnumクラスが メソッドを持っている ことを思い出そう

  72. そうあなたのメソッドも Fixnumクラスに追加すればいい

  73. class Fixnum def hello "Yo!" end end

  74. さあ あなたから1に挨拶を!

  75. $ 1.hello # => "Yo!"

  76. もう少し気の利いた返事がほしいなら メッセージが別のオブジェクトを 受け取れるようにすればいい

  77. class Fixnum def hello(name) "Yo! #{name}" end end

  78. そしてあなたの名前を渡す

  79. $ 1.hello("Charlie") # => "Yo! Charlie"

  80. ここまでの説明が理解できたなら 挨拶に答えられるようになったのが 1だけではない ということが分かるだろう

  81. $ 2.hello("Ken") # => "Yo! Ken" $ 24.hello("ジャック・バウアー") # =>

    "Yo! ジャック・バウアー" $ 365.hello(365) # => "Yo! 365"
  82. そう今や Fixnumクラスに属する すべての数字が

  83. あなたが作った helloに答えられる!

  84. 先のコードの最後の式を⾒て ドキリとする⼈もいるかもしれない

  85. メソッドに渡すオブジェクトを 「引数」と呼ぶけれども

  86. 渡されるものが オブジェクトである限り Rubyは それを引数として受け⼊れる

  87. 上の2つは ⽂字列のオブジェクトを 引数として渡し

  88. 最後のものは今まで⾒てきた 数のオブジェクトを渡している

  89. すでにオブジェクトからの応答が オブジェクトであることを 理解したあなたなら

  90. 次のコードも理解できるだろう

  91. $ 1.hello(2.hello("Ma")) # => "Yo! Yo! Ma"

  92. $ at_exit { $ puts "Thank you for watching!" $

    }