Slide 1

Slide 1 text

Ruby30 Ruby でハローワールドする30 の方法

Slide 2

Slide 2 text

i = 30 "#{i} 周年おめでとうございます " + ? ! * i

Slide 3

Slide 3 text

30 周年ということで、 Ruby でハローワ ールドする 30 の方法を紹介します

Slide 4

Slide 4 text

レギュレーション: "Hello, world!" を 改行込みで出力する 警告やエラーを出さない

Slide 5

Slide 5 text

Ruby で Hello world する方法その 1 # 一番単純 puts "Hello, world!"

Slide 6

Slide 6 text

Ruby で Hello world する方法その 2 # 文字列埋め込み hello = "Hello" world = 'world!' puts "#{hello}, #{world}"

Slide 7

Slide 7 text

Ruby で Hello world する方法その 3 # フォーマット文字列、`ord` で得られた数字を使う printf "%s, %c%c%c%c%c%c%c", "Hello", 119, 111, 114, 108, 100, 33, 10

Slide 8

Slide 8 text

Ruby で Hello world する方法その 4 # 標準出力($> )に文字列を追加する $><<"Hello, world!\n"

Slide 9

Slide 9 text

Ruby で Hello world する方法その 5 # 正規表現でキャプチャして連結 str = "Hello, ruby30 world!" md = str.match /^(\w+).+(\w{5,}!)/ puts md.captures.join(', ')

Slide 10

Slide 10 text

Ruby で Hello world する方法その 6 # シンボルのリテラルにもいくつか書き方がある print %s|Hello, world| puts :!

Slide 11

Slide 11 text

Ruby で Hello world する方法その 7 # Ruby には「文字」リテラルがあるのでそれらを結合する puts ?H << ?e << ?l << ?l << ?o << ?, << ?\u0020 << ?w << ?o << ?r << ?l << ?d << ?!

Slide 12

Slide 12 text

Ruby で Hello world する方法その 8 # ヒアドキュメントで縦書きを実現 puts <<"HELLOWORLD".chomp.gsub(/([a-zA-Z, ])?\n/) {|match| match[0]} H e l l o , \x20 w o r l d ! HELLOWORLD

Slide 13

Slide 13 text

Ruby で Hello world する方法その 9 # 文字列の生成方法は色々ある puts %q(Hello) + String.new(', ') + String(:world!)

Slide 14

Slide 14 text

Ruby で Hello world する方法その 10 # "Hello, world!".each_codepoint.map{|n| n.to_s(16) } # で得られたコードポイントの配列を文字列に戻す ["48", "65", "6c", "6c", "6f", "2c", "20", "77", "6f", "72", "6c", "64", "21", "a"].each do |codepoint| print codepoint.to_i(16).chr end

Slide 15

Slide 15 text

Ruby で Hello world する方法その 11 # eval するだけだが、よく見るとネストしている eval("eval %q(puts 'Hello, world!')")

Slide 16

Slide 16 text

Ruby で Hello world する方法その 12 # eval の仲間のinstance_eval を使う、self はHello, world! "Hello, world!".instance_eval do puts self end

Slide 17

Slide 17 text

Ruby で Hello world する方法その 13 # then とmethod メソッドのProc 化を組み合わせる "Hello, world!".then(&method(:puts))

Slide 18

Slide 18 text

Ruby で Hello world する方法その 14 # p はinspect を内部で呼ぶので、inspect が文字列を返せばよい str = "" def str.inspect "Hello, world!" end p str

Slide 19

Slide 19 text

Ruby で Hello world する方法その 15 # puts は内部でto_s を呼ぶので、to_s がHello, world! を返せばよい class Okura def name = "OKURA Masafumi" def work_as = "Freelancer" def available_for_hiring? = true def organizer_of = "Kaigi on Rails" def to_s "Hello, world!" end end puts Okura.new

Slide 20

Slide 20 text

Ruby で Hello world する方法その 16 # 全てのputs がHello, world! になる module HelloWorld def puts(*args) super("Hello, world!") end end Kernel.prepend(HelloWorld) puts

Slide 21

Slide 21 text

Ruby で Hello world する方法その 17 # 素直に新しいメソッドを定義する module HelloWorld def put_hello_world puts("Hello, world!") end end Kernel.include(HelloWorld) put_hello_world

Slide 22

Slide 22 text

Ruby で Hello world する方法その 18 # String をオープンクラスする class String def print_self puts self end end "Hello, world!".print_self

Slide 23

Slide 23 text

Ruby で Hello world する方法その 19 # オープンクラスはお行儀が悪いのでrefinements を使う using Module.new { refine String do def print_self puts self end end } "Hello, world!".print_self

Slide 24

Slide 24 text

Ruby で Hello world する方法その 20 # メソッドチェーンは便利 class String ("a".."z").each do |char| define_method(char) { self + char } end def comma = self + ?, def space = self + ' ' def ! = self + ?! def puts = Kernel.puts(self) end "H".e.l.l.o.comma.space.w.o.r.l.d.!.puts

Slide 25

Slide 25 text

Ruby で Hello world する方法その 21 # 文字列は隣接させると連結される # % リテラルの区切り文字には空白が使える # Thanks @tompng puts(% Hello, ' world'"!")

Slide 26

Slide 26 text

Ruby で Hello world する方法その 22 # 無意味なオブジェクト指向 class Printer def initialize(object) @object = object end def print Kernel.print @object puts end end Printer.new("Hello, world!").print

Slide 27

Slide 27 text

Ruby で Hello world する方法その 23 # puts はKernel のインスタンスメソッドなので、適当なオブジェクトにbind できる Kernel.instance_method(:puts).bind(Object.new).call("Hello, world!")

Slide 28

Slide 28 text

Ruby で Hello world する方法その 24 # どうしてこうなるのかわからない # Dummy クラスは警告抑制に必要、say メソッドはないとSyntaxError class Dummy def method_missing(meth, *args, &blk) puts meth end def self.const_missing(name) print name.to_s + ', ' end def say(*) end end Dummy.new.instance_eval("say Hello, world!")

Slide 29

Slide 29 text

Ruby で Hello world する方法その 25 # クラス名は文字列の代わりになる class Hello end class World def self.to_s = 'world!' end print "#{Hello}, #{World}\n"

Slide 30

Slide 30 text

Ruby で Hello world する方法その 26 # world! の返り値を、world! の中で定義したhello メソッドで利用する def world! def hello(str) puts "#{__method__.to_s.capitalize}, #{str}" end __method__.to_s end hello world!

Slide 31

Slide 31 text

Ruby で Hello world する方法その 27 # exit してもハローワールドはできる at_exit { puts "world!" } print "Hello, " exit

Slide 32

Slide 32 text

Ruby で Hello world する方法その 28 # 文字列をバラしてから復元する ORDER = { "H": [1], "e": [2], "l": [3, 4, 11], "o": [5, 9], ",": [6], " ": [7], "w": [8], "r": [10], "d": [12], "!": [13] } puts "Hello, world!".chars.shuffle.each_with_object("a"*13) { |char, result| index = ORDER[char.to_sym] result[index.shift - 1] = char }

Slide 33

Slide 33 text

Ruby で Hello world する方法その 29 # 変数名を使う、大文字や空白、! は使えないので工夫が必要 hello = nil world = nil binding.local_variables.each_with_index do |var, i| i.zero? ? (print var.capitalize) : (puts ", #{var}!") end

Slide 34

Slide 34 text

Ruby で Hello world する方法その 30 # Fiber で記号に関して処理を中断して、記号を入れたら再開する f = Fiber.new do "Helloworld".each_char.with_index do |c, idx| print c Fiber.yield if idx == 4 || idx == 10 end end f.resume print ", " f.resume puts "!"

Slide 35

Slide 35 text

ご清聴ありがとうございました