Skip to content

Instantly share code, notes, and snippets.

@udzura udzura/LICENSE
Last active Jul 9, 2019

Embed
What would you like to do?
やわらかRuby
やわらかRubyはCC BY 4.0 で提供します。
詳細: https://creativecommons.org/licenses/by/4.0/deed.ja
This work is licensed under a Creative Commons Attribution 4.0 International License.
See also: https://creativecommons.org/licenses/by/4.0/deed

Setup

chapter 0: Ruby をインストールする

  • rbenv
  • ruby-build

問0-1

  • 以下のコマンドの出力結果を確認してみよう
# (1)
rbenv init -
# (2)
which ruby
# (3)
file `which ruby`
# (3')
file /usr/bin/ruby
# (4)
cat `which ruby`

Rubyを遊び尽くす弾丸ツアー

chapter 1: 整数、文字列、配列、ハッシュ

  • 頻出表現
String#to_i
#=Stringクラスのオブジェクトのメソッドto_i
3.odd?
#=> true
4.odd?
#=> false

"paperboy".size
#=> 8
"paperboy".count("p")
#=> 2
"paperboy".reverse
#=> "yobrepap"
[1, 4, 5, 3, 2].sort
#=> [1, 2, 3, 4, 5]

問1-1

  • 次のメソッドは存在する?存在しない?

    1. Array#shuffle # ランダムに並び替える
    1. String#hexadecimal # 16進数として解釈する
    1. Integer#hours # 時間だとして何秒か表示する

chapter 2: ビックリとハテナ

  • ハテナで終わるメソッドはtrueまたはfalseを返す。?で終わることが出来るので、わざわざ is_~ を付けない。
  • ビックリで終わるメソッドは、元のオブジェクトに操作を加える(破壊的メソッド)
    • ただし、破壊的でないメソッドとかならず対になって存在する(Array#concatなどはビックリじゃないけど破壊的)
str = "quail"
str.reverse
#=> "liauq"
str
#=> "quail"
str.reverse!
#=> "liauq"
str
#=> "liauq"

str.start_with? "q"
#=> false

問2-1

  • 以下のstr1とstr2の違いは何?
str1 = str2 = "paperboy"
str1 += "&co." 
str2 << "&co."
# ヒント
str1 == str2 #=> ?
str1.object_id == str2.object_id #=> ?

問2-2

  • こうするとstr1は変更されるが、
str1 = "paperboy"
str1.tr! "p", "q"
  • こうするとstr2は変更されない。String#dupは何をしている?
str2 = "paperboy"
str2.dup.tr! "p", "q"

問2-3

  • 整数のクラス(Integer)に「!」で終わるメソッドはあるか?それはなぜか?

chapter 3: ブロック

  • 3回繰り返す
3.times do
  puts "Hello, world!"
end
  • 配列に対して繰り返す
["dog", "cat", "chicken"].each do |name|
  puts sprintf("%s is an animal", name)
end
  • Fileを読み込んで必ず閉じる
File.open("/etc/hosts") do |f|
  puts f.read
end

問3-1

p = Proc.new do |obj|
  p obj
end
    1. p はどんなオブジェクト?irbで調べてみよう
    1. また、以下を実行するとどう表示される?
["dog", "cat", "chicken"].each &p
["dog", "cat", "chicken"].each p

p.call "dog"

chapter 4: クラスとモジュール

class Animal
  def warm_body?
    false
  end
end

class Fish < Animal
end

class Mammal < Animal
  def warm_body?
    true
  end
end

Fish.new.warm_body?
Mammal.new.warm_body?
  • モジュールと三角継承
class Animal
end
class Mammal < Animal
  def swimmable?
    false
  end
end
module Swimmable
  def swimmable?
    true
  end
end

class Fish < Animal
  include Swimmable
end

class Dolphin < Mammal
  include Swimmable
end

Fish.new.swimmable?
Mammal.new.swimmable?
Dolphin.new.swimmable?
  • モジュールとは何だろう?

    • クラスのメソッド定義の一部を切り出したもの
    • 便利メソッドを束ねたもの
    • 名前空間
  • インスタンス変数

class Dog
  def initialize(name)
    @name = name
  end

  def info
    "This dog's name is #{@name}"
  end
end

dog = Dog.new("Akubi")
puts dog.info

# こうでもいいかも
class Dog
  attr_accessor :name

  def initialize(name)
    self.name = name
  end

  def info
    "This dog's name is #{name}"
  end
end
  • クラスメソッドの定義
class Dog
  class << self
    def print_info(name)
      dog = new(name)
      puts dog.info
    end
  end
end

問4-1

  • 以下のメソッドの結果はどういう意味か?
Dolphin.ancestors

問4-2

    1. Rubyの組み込みクラスの継承関係のドキュメントを探して、確認してみよう
    1. また、Enumerable Comperable を継承しているクラスは何か確認してみよう

chapter 5: オープンクラス

def fizzbuzz(n)
  (1..n).each do |i|
    out = ""
    if (i % 3).zero?
      out = "Fizz"
    end
    if (i % 5).zero?
      out += "Buzz"
    end
    out = i.to_s if out.empty?
    puts out
  end
end
  • 100.to_fizzbuzz って呼び出したくない?
class Integer
  def to_fizzbuzz
    (1..self).each do |i|
      out = ""
     if (i % 3).zero?
        out = "Fizz"
      end
      if (i % 5).zero?
        out += "Buzz"
      end
      out = i.to_s if out.empty?
      puts out
    end
  end
end

200.to_fizzbuzz

問5-1

  • Integer#hours を自作しよう

問5-2

  • エスケープシーケンスについて調べて、 String#to_red を追加しよう

chapter 6: ほんのちょっとだけメタプログラミング

bloc = proc do
  puts reverse
  puts size
  puts chars.shuffle.join
end

bloc.call
#=> NoMethodError!

str = "paperboy"
str.instance_eval &bloc
#=> !!!

問6-1

    1. 実行して、その出力結果を記述しよう
    1. どういうことか考えるだけ考えてみよう

問6-2

  • 以下と比較しよう。 Object#indtance_evalKernel#eval はどう違う?
methods = "chars.shuffle.join"
str = "paperboy"
eval "puts str.#{methods}"

ちょっとだけ実用Ruby

chapter 7: RubyGems

  • Rubyのパッケージマネージャー
  • Rubyの便利プログラムのひとまとまり=gem
$ gem list -rd hashie

*** REMOTE GEMS ***

hashie (2.0.5)
    Authors: Michael Bleigh, Jerry Cheung
    Homepage: https://github.com/intridea/hashie

    Your friendly neighborhood hash toolkit.
  • インストール
$ gem install hashie
  • 使うには
require "hashie"
options = Hashie::Mash.new(name: "Akubi")
options.name
  • gem以外にも、「標準添付ライブラリ」というものもあるよ
require "uri"
URI.parse "https://lolipop.jp"
  • gemの正体
    • 実は、特定の構成のファイル群をgzipで固めただけのもの
    • 一部はビルドスクリプトも付いている
    • インストール時に展開して特定のディレクトリに配置する

問7-1

  • インストールしたgemについて、以下の表示を確認しよう
$ gem list -d hashie

問7-2

  • RubyGems.org で適当なgemをダウンロードして、展開して中身を見てみよう

chapter 8: Bundler

  • 「プロジェクトでどんなgemを使うか」を管理するためのライブラリ
  • もともとRailsのgem管理システムが進化したもの
source "https://rubygems.org"

gem "hashie"
gem "coderay"
gem "redcarpet"
## brew install libxml2 libxslt
$ cat Gemfile
$ bundle install
require "bundler/setup"
Bundler.require
# sample use coderay
puts CodeRay.scan(<<EOC, :ruby).terminal
def add(some)
  1 + 2 + some
end
EOC
$ bundle exec ruby sample.rb

問8-1

  • Gemfile.lock の中身を見てみよう

問8-2

  • Gemfileのgem "redcarpet" をコメントアウトしたりしなかったりした状態で、以下のスクリプトの実行結果を見てみよう
    • ヒント: スクリプトは、Gemfileと同じディレクトリに配置しないとうまく行かないかも
require "bundler/setup"
require "redcarpet"
p defined?(Redcarpet)

chapter 9: Sinatra で遊んでみよう

$ gem install sinatra
$ ruby -rsinatra -e "get('/') { 'Fastest web development' }"
  • 少しアプリらしくする
Gemfile
app.rb
source "https://rubygems.org"
gem "sinatra"
require "sinatra"

get "/" do
  'Fastest web development'
end
$ bundle exec ruby app.rb

DSLと言う考え方

  • get ~ do でルーティングと処理を表現する
  • get はRubyのメソッドではなく、Sinatraがウェブのルーティングを表現するために追加した専用の言語
  • use, set なども追加される

問9-1

  • じゃんけんをするウェブアプリケーションを作ってみよう
require "sinatra"

get "/" do
  erb [(1)???]
end

[(2)???] "/result" do
  @choice = [(3)???]
  @op_choice = %w(goo choki paa).sample
  win_to_lose = {
    "goo" => "choki",
    "choki" => "paa",
    "paa" => "goo",
  }
  @result = if win_to_lose[@choice] == @op_choice
    "Won!"
  elsif @choice == @op_choice
    "Draw"
  else
    "Lost..."
  end
  erb :result
end

__END__
@ index
<html>
<h1>じゃんけん?</h1>
<form action='/result' method='post'>
  <select name='choice'>
    <option value='goo'>グー</option>
    <option value='choki'>チョキ</option>
    <option value='paa'>パー</option>
  </select>
<input type='submit' />
</form>
</html>

@ result
<html>
<h1>結果:</h1>
<p><%= [(4)???] %></p>
<p>自分:<%= [(5)???] %> 相手:<%= [(6)???] %></p>
</html>

問9-2

  • さっきのアプリケーションに、RubyのみでBasic認証の機能を追加するにはどうする?
    • ヒント: Rack Middleware

最後に: Ruby情報(日本語)

るりま

るびま

ドットインストール

Ruby Toolbox

@skuroki

This comment has been minimized.

Copy link

commented Nov 21, 2013

gem install hahsie

@udzura

This comment has been minimized.

Copy link
Owner Author

commented Dec 29, 2013

はい

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.