Rubyのチートシート / メソッドと例外処理

- - - - - - - - - - - 
ブログを更新しました。<a href="http://workabroad.jp/posts/2059">元の記事はコチラ</a>
- - - - - - - - - - - 
メソッドの基本的な書き方と例外処理。Railsチュートリアルを初めて読んだ時にcurrent_user=()みたいなメソッドがあって、え？てなったのを覚えてる…。



```ruby

# ---------------------------------------------- #
# メソッド
# ---------------------------------------------- #

puts "\n\n############## Option Hash ##############\n\n"

# **BAD***
# 引数が何個必要なのか、どの場所にどの引数なのか混乱しやすい
# デフォルト値が設定されていない引数を渡し忘れるとエラーになる
def get_profile_bad(user_id, name, email, age = 0, gender = 'femal')
	puts user_id
	puts name
	puts email
	puts age
	puts gender
end

# **GOOD**
# 必須でない引数はハッシュで受け取るとスッキリ
# user_id以外の引数はオプションなので渡さなくてもエラーにはならない
def set_profile_good(user_id, options = {})
	puts "ID   : #{user_id}"
	puts "NAME : #{options[:name]}"
	puts "MAIL : #{options[:email]}"
	puts "AGE  : #{options[:age]}"
	puts "GEN  : #{options[:gender]}"
end


# 実行する時は改行して見やすく

puts "\n--- GOOD ---\n\n"

set_profile_good(14,
		name:   "my name here",
		email:  "email@email.com",
		age:    99,
		gender: "male"
)


# 結果は同じだけど読みづらい

puts "\n--- BAD ---\n\n"

set_profile_good(14, {name: "my name here", email: "email@email.com", age: 99, gender: "male"})


# optionsを渡さなくても実行可能

puts "\n--- options省略 ---\n\n"

set_profile_good(14)





puts "\n\n############## 特殊な記号 ##############\n\n"


# "*"がついた引数で、それ以降の引数を配列として受け取る
# ---------------------------------------------- #
puts "--- Splat Arguments ---\n\n"

def show_names(status, *names)
	puts "STATUS : #{status}\nNAME   : #{names.join(', ')}"
end

# "fine"以外はnamesに配列として格納される
show_names("fine", "sawada", "sakata", "suzuki", "saito")



# '!'や'?'と同じく,'='も特別な意味を持っているが強制するものではない
# '='は代入するという意味をもったメソッド
# ---------------------------------------------- #

puts "\n--- 'xx=' method  ---\n\n"

class User

	def initialize(name)
		@name = name
	end

	### アクセサメソッドを自分で定義 ###
	def name=(name)
		@name = name
	end

	def name
		@name
	end

	# xx=は単にメソッドなので、
	# @testインスタンス変数がなくても定義はできる
	def test=(text)
		puts text
	end

	### アクセサメソッドは簡単に書ける ###

	# attr_accessor :name とすればメソッドを用意しなくても
	# インスタンス変数の中身を読んだり、変更したりできるので
	# name=(name)とnameメソッドは不要

	#attr_accessor :name
	#attr_reader: :name
	#attr_writer: :name

end

user = User.new("sawada")


#nameメソッド / 単にインスタンス変数@nameを返すだけ
puts user.name

# name=()メソッド
# インスタンスメソッドだからuserから呼び出せるのは当然
user.name=("kato")
puts user.name

# ()は省略できるけど、普通はこんな書き方はしない
user.name="suzuki"
puts user.name

# xx=タイプの名前のメソッドを定義すると、同時に「=」演算子を定義することになるので
# 下のような定番の書き方で、値をインスタンス変数に代入することができる
user.name = "saito"
puts user.name

# まず書かないと思うけど
# こんな代入っぽい書き方でも普通のメソッドのように振る舞う…
user.test = "テストだよ"






puts "\n\n############## 例外処理 ##############\n\n"

# 外部のAPIがダウンしてたりとか予想できないことも起こりうるので
# そんな時にアプリの処理を止めないよう例外処理がかける
# ---------------------------------------------- #

def find_from_api(name)

	users = ["sawada", "sakata", "suzuki", "saito"]

	if users.find { |u| u == name }
		puts "We found #{name} in users!\n"
	else
		raise StandardError.new("Hey! We got an error.\n")
	end
end


puts "--- 基本 ---\n\n"

begin
	find_from_api("batman")
rescue => e
	puts "Not found. #{e.message}" #エラーオブジェクトを受け取って表示
ensure
	find_from_api("sawada") #例外が発生しても行う処理
end


puts "\n--- 数回トライ ---\n\n"

error_count = 0
begin
	finding_from_api("sawada") #存在しないメソッド
rescue => e
	error_count += 1
	if error_count < 4
		puts "#{error_count}回目のエラーだよ…"
		puts "#{e.message}"
		retry
	end
ensure
	puts "あきらめた！"
end

```

上のコードを実行するとこうなるはずです。


```

############## Option Hash ##############


--- GOOD ---

ID   : 14
NAME : my name here
MAIL : email@email.com
AGE  : 99
GEN  : male

--- BAD ---

ID   : 14
NAME : my name here
MAIL : email@email.com
AGE  : 99
GEN  : male

--- options省略 ---

ID   : 14
NAME : 
MAIL : 
AGE  : 
GEN  : 


############## 特殊な記号 ##############

--- Splat Arguments ---

STATUS : fine
NAME   : sawada, sakata, suzuki, saito

--- 'xx=' method  ---

sawada
kato
suzuki
saito
テストだよ


############## 例外処理 ##############

--- 基本 ---

Not found. Hey! We got an error.
We found sawada in users!

--- 数回トライ ---

1回目のエラーだよ…
undefined method `finding_from_api' for main:Object
2回目のエラーだよ…
undefined method `finding_from_api' for main:Object
3回目のエラーだよ…
undefined method `finding_from_api' for main:Object
あきらめた！

```

Rubyで使われる特殊な記号（!とか?とか）は下記サイトがとても参考になります。

[Rubyで使われる記号の意味](http://docs.ruby-lang.org/ja/1.9.3/doc/symref.html#eq)
[Ruby QuickRef](http://www.zenspider.com/Languages/Ruby/QuickRef.html)

レイアウトが崩れていたので修正しました。

 → <a href="http://workabroad.jp/posts/2059">http://workabroad.jp/posts/2059</a>