cv.cm

コーディング · プログラミング言語

Ruby入門チュートリアル(初心者向け)

約9分で読めます

結論

Rubyは、読み書きしていて心地よいことを目指して設計された、動的なオブジェクト指向のスクリプト言語です。puts "Hello, world" を hello.rb に保存して ruby hello.rb で実行します。Rubyではすべてがオブジェクトで、数値や nil も例外ではありません。def で定義するメソッド、配列とハッシュ、each や map などのイテレータに渡すブロック、クラスとモジュール、begin/rescue による例外処理が中心的な内容です。

正規表現テストを開く

Rubyとは何か、何に使われるか

Rubyは日本のまつもとゆきひろ(Matz)氏が作り、「プログラマーを幸せにする」ことを目標に1995年に最初のバージョンが公開されました。GitHubやShopifyなどのサイトを支えるWebフレームワークRuby on Railsによって広く知られるようになりました。Webアプリケーション、スクリプトや自動化、HomebrewやCocoaPodsといった開発者向けツールに使われています。標準の実装はCRuby(MRIとも呼ばれます)です。

Rubyのインストールと Hello, world の実行

macOSや多くのLinuxにはRubyが入っていますが、古いことが多いため、rbenv、asdf、miseなどのバージョン管理ツール、またはWindowsならRubyInstallerで、現行のRuby 3をインストールしましょう。ruby -v で確認します。

puts "Hello, world"
ruby hello.rb
# Hello, world
irb          # interactive Ruby shell

puts は値を表示し、最後に改行を付けます。意味が明らかな場合、メソッドの引数を囲む括弧は省略できます。

変数と基本の型

変数は宣言が不要で、任意のオブジェクトを保持できます。名前には慣習として snake_case を使います。定数は大文字で始まります。

クラス例備考
Integer42, 2**100任意の大きさ
Float3.14倍精度
String"hi #{name}", 'hi'変更可能。二重引用符では式が展開される
Symbol:name変更できない識別子。ハッシュのキーとしてよく使われる
true, falsetruefalse と nil だけが偽
NilClassnil値なし
Array, Hash[1, 2], {a: 1}組み込みのコレクション
name = "Ada"
count = 7
puts "#{name} has #{count} items"   # Ada has 7 items
puts count / 2, count / 2.0         # 3, then 3.5
puts "12".to_i + 1                  # 13
puts 5.class, nil.to_a.inspect      # Integer, then []
puts 0 ? "0 is truthy" : "falsy"    # 0 is truthy

制御構文

score = 72
if score >= 90
  puts "A"
elsif score >= 70
  puts "B"          # B
else
  puts "C"
end

puts "pass" unless score < 50    # statement modifier

3.times { |i| print i, " " }     # 0 1 2
puts

n = 10
n /= 2 while n > 1
puts n                           # 1

kind = case "SAT"
       when "SAT", "SUN" then "weekend"
       else "weekday"
       end
puts kind                        # weekend

ブロックは波括弧ではなく end で終わります。Rubyのコードは通常、半角スペース2つでインデントします。

メソッド

メソッドは最後の式の値を返すため、return は不要なことが多くあります。慣習として、真偽値を返すメソッドは ? で終わり、レシーバをその場で変更するメソッドは ! で終わります。

def greet(name, greeting: "Hello")
  "#{greeting}, #{name}!"
end

def total(*nums)
  nums.sum
end

puts greet("Lin")                   # Hello, Lin!
puts greet("Lin", greeting: "Hi")   # Hi, Lin!
puts total(1, 2, 3)                 # 6
puts 4.even?, "abc".upcase          # true, then ABC

s = "hello"
s.upcase!          # modifies s in place
puts s             # HELLO

配列とハッシュ

nums = [3, 1, 2]
nums << 5
p nums.sort, nums.first, nums.last   # [1, 2, 3, 5] then 3 then 5
p nums.sort[1..2]                    # [2, 3]

ages = { "ann" => 31, "bob" => 25 }
ages["cy"] = 40
ages.each { |person, age| puts "#{person} is #{age}" }
p ages.fetch("zed", 0)               # 0

user = { name: "Ann", city: "Oslo" } # symbol keys
p user[:name]                        # "Ann"

p は値の inspect 形式を表示します。引用符や括弧が見えるので、デバッグに便利です。

特徴的な機能:ブロックとイテレータ

ブロックはメソッドに渡すコードのかたまりで、1行なら { ... }、複数行なら do ... end で書きます。Rubyの繰り返し処理は for ループではなく、主にブロックで行います。Enumerable のメソッドを使うと、データ変換を短く書けます。

nums = [1, 2, 3, 4, 5]
p nums.map { |n| n * n }               # [1, 4, 9, 16, 25]
p nums.select(&:even?)                 # [2, 4]
p nums.reduce(0) { |sum, n| sum + n }  # 15
p nums.each_slice(2).to_a              # [[1, 2], [3, 4], [5]]
p %w[pear fig apple].sort_by(&:length) # ["fig", "pear", "apple"]

def twice
  yield
  yield
end
twice { puts "hi" }   # prints hi two times

&:even? は { |n| n.even? } の省略形です。自分で定義したメソッドも、ブロックを受け取って yield で呼び出せます。

クラスとモジュール

module Greeter
  def hello
    "Hello from #{name}"
  end
end

class Account
  include Greeter          # mix in module methods
  attr_reader :name, :balance

  def initialize(name)
    @name = name           # @ marks an instance variable
    @balance = 0
  end

  def deposit(amount)
    raise ArgumentError, "amount must be positive" unless amount.positive?
    @balance += amount
    self
  end

  def to_s = "#{name}: #{balance}"
end

acc = Account.new("Ann")
acc.deposit(30).deposit(20)
puts acc        # Ann: 50
puts acc.hello  # Hello from Ann

attr_reader はゲッターメソッドを生成します。モジュールは、多くのクラスにミックスインできるメソッドをまとめるもので、Rubyは多重継承の代わりにこれを使います。1行形式の def to_s = ... にはRuby 3.0以降が必要です。

エラー処理

def parse_age(text)
  age = Integer(text)       # raises ArgumentError on bad input
  raise ArgumentError, "negative age" if age.negative?
  age
end

begin
  puts parse_age("41")      # 41
  puts parse_age("abc")
rescue ArgumentError => e
  puts "error: #{e.message}"  # error: invalid value for Integer(): "abc"
ensure
  puts "done"
end

rescue は例外を捕捉し、ensure は必ず実行されます。メソッドの中では、begin なしで直接 rescue を書けます。

小さな完成プログラム:単語の出現頻度

path = ARGV.fetch(0) { abort "usage: ruby words.rb FILE" }

begin
  text = File.read(path).downcase
rescue Errno::ENOENT
  abort "file not found: #{path}"
end

counts = text.scan(/[a-z']+/).tally
counts.max_by(5) { |_word, n| n }.each do |word, n|
  puts format("%5d  %s", n, word)
end

ruby words.rb notes.txt で実行します。tally は等しい要素の数をハッシュに集計し、max_by(5) は回数の多い上位5件の要素を返します。

初心者がよくやる間違い

  • if、def、class、do ブロックを閉じる end を忘れる。
  • 文字列キーとシンボルキーを混在させる。h["name"] と h[:name] は別のキーです。
  • 単一引用符を使いながら、#{} による式展開が働くと期待する。
  • ! 付きのメソッドを呼んで、元のオブジェクトが変更されたことに気づかない。
  • バージョン管理ツールでインストールした現行バージョンではなく、古いシステムのRubyを使う。

次のステップ

ruby-lang.orgのドキュメントのページから始めましょう。クイックスタート「Ruby in Twenty Minutes」もあります。コアと標準ライブラリのリファレンスにはdocs.ruby-lang.orgを使います。依存関係管理のBundlerとgem、テストのRSpecまたはMinitestを学び、Webアプリケーションを作りたいならRuby on Railsに進みます。

よくある質問

Rubyは今でも使われていますか?

はい。Ruby on RailsはGitHubやShopifyをはじめ、多くの確立したWebサービスを動かしており、Rubyはスクリプトや開発者向けツールでも一般的です。新規プロジェクトではPythonやJavaScriptほど一般的ではありませんが、活発に開発が続いています。

RubyとRuby on Railsの違いは何ですか?

Rubyはプログラミング言語です。RailsはRubyで書かれたWebフレームワークで、ルーティング、データベースアクセス、ページテンプレートを提供します。

Rubyのシンボルとは何ですか?

:name のようなシンボルは、変更できない一意の識別子です。同じシンボルは常に同じオブジェクトなので、ハッシュのキーやオプション名に効率的です。

初心者にはRubyとPythonのどちらがよいですか?

どちらも読みやすい文法で、最初の言語に向いています。Pythonは、特にデータサイエンスなど用途が広く、Rubyは表現力が高く、RailsによるWeb開発に強みがあります。

コーディング講座の一覧