LoginSignup
1
1

More than 5 years have passed since last update.

Ruby 2.1入門のまとめ

Last updated at Posted at 2016-09-09

こちらruby説明が良かったですが読み辛いのでまとめてみた。

若手エンジニア/初心者のためのRuby 2.1入門:
http://www.atmarkit.co.jp/ait/kw/ruby_nyumon.html

他入門に参照になるもの:
Ruby 2.1 / Rails4.1 の意外に忘れられている便利なメソッド:
http://ruby-rails.hatenadiary.com/entry/20150101/1420049679
Ruby基礎文法最速マスター:
http://route477.net/d/?date=20100125

2.Ruby 2.1の基本構文/基本文法

定数

大文字から始まれば「定数だ」と認識される

QUEEN = 42
#or 
#Queen = 12

freezeを入れることでjavaのfinal的役割をする認識は間違い。
なので
Stringなど定数はfreezeをつけるべきだが
int定数はfreezeしなくでもいい
冗長になりがち

TEAPOT = "tea".freeze
#TEAPOT = "coffee"は警告があるだけで変更ができてしまう。
#TEAPOT.capitalize!のようなことができないようにするだけだ。

ifも戻り値がある

teapot = if ARGV[0].to_i == 42
  "tea"
else
  "coffee"
end
puts teapot

case

最後のelseで他の場合に実行するが、javaのdefaultに似ている

case ARGV[0].to_i
when 0
  puts "zero"
when 1
  puts "one"
when 2, 3
  puts "two or three"
else
  puts "other"
end

コメント

# コメント
=begin
こちらもコメント
=end

3.Rubyの配列、ハッシュテーブル

Array

#オブジェクト作成
array = []
array = Array.new

#追加,push,<<
array.push(1)
array << 2
array << "3"

#逆参照
array[-1]

#範囲指定
array[1..2]
# => [2,"3"]

#削除
array.delete(1) #指定した値を検索して削除
array.delete_at(0)  #指定した位置の要素を削除
array.clear #全部削除

#pop,push,shift,rotate省略

#arrayを逆順にする
array.reverse #swift言語のreverse()と同じ
array.reverse! #自身も変更

#sort,sort_by,できれば高速なsort_byを使おう
array.sort_by

#「宇宙船演算子」
1 <=> 2
# -1など

#配列をランダムに
array.shuffle

#ランダムに二つの要素を取り出す
array.samle(2)

#要素を検索して位置を返す
array.index(3)
array.rindex(3) #後ろから数得る

#重複要素取り除く
array.uniq # or array.uniq!

#nilを取り除く
array.compact #or compact!

#二つの配列を結合
#push,<<はそのまま結合されてしまうが、こっちがほうがarrayのflat化できる->平滑化
array1.concat(array2)

#zip省略

#map あとで説明

上記 !が付いたメソッドを「破壊的メソッド」と呼ぶ

Hash

#初期化
hash = {}
hash = Hash.new

#hashオブジェクト作成
hash = {"jack" => 11, "queen" => 12, :king => 13}
#シンタックスシュガー」(糖衣構文、プログラミング言語において、読み書きのしやすさのために導入される構文)
#これで =>が省略できる
hash = {jack: 11, queen: 12, king: 13}

#アクセス
hash["queen"]
hash[:king]

#キー、値一覧
hash.keys
hash.values

#追加
hash[:ace] = 1
hash["child"] = 12

#削除
hash.delete["jack"]

#clear
hash.clear

#hashを配列に
hash.to_a #[[:jack, 11], [:queen, 12], [:king, 13]]

4.RubyのRangeクラスと範囲オブジェクト、範囲演算子、イテレーター

Array

puts ".."
# 5を含む、すなわち<= 5
for i in 1..5
  p i
end
puts "..."
# 5を含まない、すなわち < 5
for i in 1...5
  p i
end

Range

Range.new(1, 3) #=> 1..3

文字範囲

# a, b, c, d
puts "alphabets"
for alphabet in "a".."d"
  puts alphabet
end
# $, %, &
puts "symbols"
for symbol in "$".."&"
  puts symbol
end
# 0, 1, 2, 3
puts "numbers"
for number in "0".."3"
  puts number
end
# あ, ぃ, い, ぅ, う
puts "hiragana"
for hiragana in "あ".."う"
  puts hiragana
end

出力結果が面白!!!

alphabets
a
b
c
d
symbols
$
%
&
numbers
0 
1
2
3
hiragana
あ
ぃ
い
ぅ
う
for string in "aa".."cc"
  puts string
end
$ ruby range_04.rb
aa
ab
ac
: (中略)
az
ba
bb
bc
: (中略)
bz
ca
cb
cc

検索

(0..5).include?(5) #true

#cover省略

要素

(1...5).first #1
(1...5).first(2) # [1,2]

#lastは同じ
#他step,n個おきに処理
(0..10).step(3) {|i| puts i}

loop

#配列
["alice", "in", "wonderland"].each do |term|
  puts term
end

# index付き
["alice", "in", "wonderland"].each_with_index do |term, index|
  puts "#{index}: #{term}"
end

#逆
["alice", "in", "wonderland"].reverse_each do |term|
  puts term
end


# Hash
{jack: 11, queen: 12, king: 13}.each do |key, value|
  puts "key: #{key}, value: #{value}"
end

5.RubyのString/Regexpクラスによる強力な文字列操作/正規表現

teapot = "tea"
#先頭文字だけ大文字に,他は小文字
teapot.capitalize #=> "Tea"

#大文字,小文字
teapot.upcase
teapot.downcase

#大文字・小文字を入れ替え
teapot.capitalize.swapcase
#=> "tEA"

#String#strip/#lstrip/#rstripで空白文字の除去
[1] pry(main)> teapot = "   tea   "
=> "   tea   "
[2] pry(main)> teapot.strip
=> "tea"
[3] pry(main)> teapot.lstrip
=> "tea   "
[4] pry(main)> teapot.rstrip
=> "   tea"

#each_char,一文字ずつしょる
#each_line, 一行ずつ処理

#分解して配列にする
"Alice".chars
#行ごと分解して配列にする
"Alice found\na bottle".lines


#結合
#+,効率悪い
str = "111" + "headers"
#代わりに効率の良いconcat,<<効率良い

teapot.concat("coffee")
teapot << "juice"

#insert挿入省略

#reverse逆転省略

#正規表現省略

6.RubyのNumericとTimeで数値と時間をさまざまな操作・演算・判定

[省略]

7. Rubyのオブジェクト指向におけるクラスとモジュール、継承、Mixin、アクセス制御の使い方

コンストラクター、インスタンス変数、キーワード引数

class Rabbit
  attr_accessor :name #外からread,write可能
  attr_reader :color, :length_of_ears #外からreadだけ

  #コンストラクター
  #name:などはキーワード引数である、デフォルト値を設定しているので、引数を省略できます。
  #また引数の順番に関係ない
  def initialize(name: "usachan", color: :white, length_of_ears: 10)
    @name = name
    @color = color
    @length_of_ears = length_of_ears
  end

  def jump
    puts "pyon! pyon!"
  end

  def pound_steamed_rice_into_rice_cake
    puts "pettan! pettan!"
  end

  def say_name
    puts "Hello, I'm #{@name}!"
  end

  def print_ears
    puts "∩_∩"
  end

  #クラスObjectクラスを継承していますのでそのto_sをoverrideすることも可能
  def to_s
    "名前: #{@name}, 毛の色: #{@color}, 耳の長さ: #{@length_of_ears}"
  end
end

継承,override

class LopEar < Rabbit
  def print_ears #メソッドをうわ書きしている
    puts "∪ ̄∪"
  end
end

アクセス制御
public: どこからでもアクセス可能
protected: クラス内、同一パッケージ、サブクラスからアクセス可
private: クラス内のみアクセス可能

private破れることが簡単

A.new.send(:private_method)

Comparable moduleによるオブジェクト比較

Comparableモジュールは、ComparableモジュールをMixinするクラスに「<=>」メソッドが定義されていることを期待しています。

class Rabbit
  include Comparable
  def <=>(other)
    @length_of_ears <=> other.length_of_ears
  end
end

継承とMixin(module)の使い分け――is-a関係とhas-a関係
is-a:「ウサギやアヒルは動物である、ニンジンは野菜である」
has-a: 何らかの共通点

8.Rubyの面白さを理解するためのメソッド、ブロック、Proc、lambda、クロージャの基本

メソッドにdefault値を入れることができる

def parrot(word="yack-yack")
  puts word
end

かっこが省略できる、ただ推奨しない

def parrot2 word
  puts word
end

parrot2 "oink"

メソッドはreturnを書かないのが基本

def sum(x, y)
  x + y
end

可変長引数は[*(アスタリスク,asterisk)」を

def sum(*args)
  puts args.class
  args.inject(:+)
end

p sum(1, 2, 3, 4, 5)
p sum(1)
p sum

キーワード引数

引数は順番を守らなくでもいい

def basic_form(a: "a", b: ["b", "b", "b"], c: :c)
  puts "a(#{a.class}): #{a}"
  puts "b(#{b.class}): #{b}"
  puts "c(#{c.class}): #{c}"
end

def complex_form(a, *b, c: "c", d:)
  puts "a(#{a.class}): #{a}"
  puts "b(#{b.class}): #{b}"
  puts "c(#{c.class}): #{c}"
  puts "d(#{d.class}): #{d}"
end

basic_form(a: "meow", b: "oink", c: :bowwow)
basic_form(a: "meow")
complex_form("oink", "bowwow", d: "meow", c: "quack")
complex_form

block

{ puts "pyonpyon" }はブロック、yieldはそのブロックを実行するだけ

def repeat(n)
  for i in 1..n
    puts "#{i} =>"
    yield
  end
end
repeat(3) { puts "pyonpyon" } 
def sum_and_exec_block(x, y)
  z = x + y
  z = yield z if block_given?
  z
end
sum_and_exec_block(10, 20) do |value|
  value + 10
end

結果は50

分かりにくいが便利なProcとlambda(ラムダ)

どちらもブロックを実行するだが "&" 付きでそのブロックが取得できる
手続きそのものをオブジェクト化して引き回す

def repeat2(n, &procedure)
  procedure.call
end

クロージャ

例1:
do...endの間はクロージャになる

prefix = "@"
["a", "b", "c"].each do |s|
  puts prefix + s
end

出力

$ ruby block06.rb
@a
@b
@c

例2:

def increase
  n = 0
  -> { n += 5 }
end

3.times { p increase.call } #実行のたびにProcオブジェクトが生成されている

puts "=================="

increase_proc = increase
3.times { p increase_proc.call } #生成したProcオブジェクトを変数increase_procに代入し、3回callしています。

出力

$ ruby block06.rb
5
5
5
==================
5
10
15

9.Rubyの例外とその捕捉――基本のbegin~rescue~endからensure、else、retry、後置rescueまで

基本的StandardErrorのエラーメインである
RuntimeException発生させる

raise "something wrong"

カスタムerrorとNotImplementedError

class UnacceptableRequidError < StandardError
  attr_reader :obj

  def initialize(obj)
    @obj = obj
  end
end

class Vessel
  def pour_out
    requid = @requid
    @requid = nil
    requid
  end

  def pour_in(requid)
    if requid.to_s == acceptance
      @requid = requid
    else
      raise UnacceptableRequidError.new(requid), "unacceptable"
    end
  end

  def acceptance
    raise NotImplementedError.new, "#acceptance is not implemented!"
  end
end

class Teapot < Vessel
  def initialize(requid)
    pour_in(requid)
  end

  def acceptance
    "tea"
  end
end

class Decanter < Vessel
  def initialize(requid)
    pour_in(requid)
  end

  def acceptance
    "wine"
  end
end

class Kettle < Vessel
  def initialize(requid)
    pour_in(requid)
  end
end

例外catch

begin
  raise "something wrong"
rescue => e
  puts "An exception is occurd!"
  p e
  p $!
end
  • 例外クラスを指定して捕捉する,javaと同じくerrorはできれば細く分割して処理する仕組みですね。
  • まずカスタムrescueに引っかかりか
  • どの例外クラスにも合致しない場合プログラムはその場で停止し、エラーメッセージが出力されますので最終的に処理するrescue StandardError => e (rescue => eと同じ)でcatchする
  • 例外の有無にかかわらず処理する「ensure」と例外が発生しなかった場合の「else」
  • ensureはjavaのfinallyに似ている。
require_relative "exception01"

begin
  teapot = Teapot.new("coffee")
  puts teapot.pour_out
rescue UnacceptableRequidError => e
  puts "Rescued in 'UnacceptableRequiedError => e'"
  p e
  p e.obj
rescue NoMethodError, ZeroDivisionError => e
  puts "Rescued in 'rescue NoMethodError, ZeroDivisionError => e'"
  p e

# 上記catchできない場合はこっちで全部catch
rescue StandardError => e # rescue => e でもOK
  puts "Rescued in 'rescue StandardError => e'"
  p e
else
  puts "There are no errors."
ensure
  puts "Ensure"
end

例外が発生してもリトライする「retry」

「省略」

後置rescue

minimumに使えそう

Teapot.new("coffee") rescue nil

10.RubyのFile/IOクラスで入力と出力、ファイルの読み取りと書き込み、フィルター作成

putsで標準出力で流したものをrabbit.txtにファイル書き込む

$ ruby -e "puts 'pyon'" > rabbit.txt
$ cat rabbit.txt

書式付き出力を行うメソッド「printf」

print "fsdaf" 
puts "fsadfasff" #printより改行が後ろに付く

[4] pry(main)> printf("%.2f", 3.14159)
3.14=> nil
[5] pry(main)> printf("%#b", 42)
0b101010=> nil
[6] pry(main)> printf("%+d %d", 42, 42)
+42 42=> nil

キーボードから入力された文字列を得るメソッド「gets」

io01.rb
print "please input a string here > "
p gets
#p gets.chompにすると改行をなくしてくれるので嬉しい

結果

$ ruby io01.rb 
please input a string here > Alice↵
"Alice\n"

テキストファイルを標準入力として使った場合のgetsの動作
[略]

ファイル読み込む

file = File.open("wonderland.txt", "r")

file.each do |line|
  puts "** #{line.chomp} **"
end

file.close

もしくはopenはブロックを引数として使えるので下記の方法もできる
この場合プログラマーは明示的に「close」メソッドを呼ぶなどの作業をしなくてもよくなります。

File.open("wonderland.txt", "r") do |file|
  file.each do |line|
    puts "** #{line.chomp} **"
  end
end

Fileクラスを使ってファイルに書き込む

File.open("teapot.txt", "w") do |file|
  file.print("darjeeling tea\n")
  file.puts("assam tea")
  file.printf("%s\n", "ceylon tea")
end

他STDOUT,STDIN

[省略]

11.RubyのThread、Fiber、Kernel、forkで並列処理やプロセスの深淵

[省略]

12.Rubyのメタプログラミング、self、特異クラス/メソッド、オープンクラスとモンキーパッチ

[省略]

実行時までわからないdefine_method

method_name = ARGV[0]

define_method method_name do
  puts "This method is named #{method_name}."
end

alice

オブジェクト固有のメソッド「特異メソッド」

array = []

def array.append_randomized_number
  self << rand(10)
end

p array.respond_to?(:append_randomized_number)
p Array.new.respond_to?(:append_randomized_number)

10.times { array.append_rondomized_number }
p array
$ ruby meta_programming_05.rb                                                                                                                     
true
false
[1, 6, 7, 6, 4, 9, 7, 7, 1, 3]

クラスメソッドと「特異クラス」

class Rabbit; end

def Rabbit.colors
  [:black, :brown, :white, :mixed]
end

p Rabbit.colors

上記、実際はよく使う下記と同じことをやっています
下記のやり方が良いと思います。

class Rabbit
  def self.colors
    [:black, :brown, :white, :mixed]
  end
end

p Rabbit.colors

また、同じく下記のような下記書き方もできるますよね

class Rabbit
  class << self
    def colors
      [:black, :brown, :white, :mixed]
    end
  end
end

オープンクラスとモンキーパッチ
+ *を再定義しているが何が特別なのか?

class Fixnum
  def +(v)
    self - v
  end
  def *(v)
    self / v
  end
end
puts 42 + 42
puts 42 * 42
$ ruby pattern_01.rb 
0 
1

ruby で動的にクラスを作る

self.class.const_set :'Creature', Class.new
=> Creature
Creature
=> Creature

以下と同じ

class Creature
end

もう1つの例:Hashをloopして動的にクラスを作成するとともにdefine_methodでmethodを追加する

{Cat: "meow", Dog: "woof", Owl: "hoot-hoot", Rabbit: "boo"}.each do |animal, roar|
  Object.const_set animal, Class.new

  Object.const_get(animal).class_eval do
    define_method :speak do |count|
      count.times { puts roar }
    end
  end
end

Cat.new.speak(2)
Dog.new.speak(2)
Owl.new.speak(2)
Rabbit.new.speak(2)

他メタプログラミング

「send」メソッド
「eval」メソッド
「instance_eval」メソッド
「method_missing」メソッド
「alias_method」メソッド
遅延評価のための「Proc」オブジェクト

13.Rubyで逆ポーランド変換機を作りgem作成&コマンドの使い方

省略

1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1