Ruby初心者を脱した人が悩みがちな、ちょっと特殊な記法・演算子・イディオム
RubyRails
初心者がRubyの基礎を覚えたところで他人のコードを読むようになると、*args や map(&:to_s) のような謎の記法がでてきます。
この手の記法は名前がわからないとググラビリティが低くなるため、人によってはつまづきとなることが多いようです。
*args
変数名の冒頭に*(アスタリスク)が付いているもので、「可変長引数」または「splat引数」とかいいます。
splatter('foo')
# => ['foo']
splatter('foo', 'bar', 'baz')
# => ['foo', 'bar', 'baz']
constants = [["π", Math::PI], ["e", Math::E]]
constants.each do |constant|
puts math_consts(*constant)
end
#=> π = 3.141592653589793
#=> e = 2.718281828459045
**opts
**(アスタリスク2つ)も可変長引数ですが、こちらはキーワード引数をハッシュで受け取ることを表しています。
オプション設定が必要なメソッドで使われることが多いと思います。
hello_with_option("Hello!", name: "nashirox")
# => Hello! nashirox@2017-02-07 16:58:46 +0900
&block
仮引数(例えばblock)に&(アンパサンド)を前置すると、「ブロック引数」となります。
メソッドはこの仮引数を介してブロックを受け取れるようになります。
this_is_block do
p "This is my block"
end
# => "This is my block"
&:method_name
mapなどブロックで配列の中身を受け取るようなメソッドに、ブロック代わりに&を前置したメソッド名(:method_name)を渡すことができます。
# 上と同じ
[1, 2, 3].map { |i| i.to_s }
# => ["1", "2", "3"]
参考:Procを制する者がRubyを制す(嘘)
_
_(アンダースコア)を用いて、使わない変数名を宣言することができます。
fruits = [
['apple', 200], ['mango', 800], ['pineapple', 500]
]
p fruits.sort{ |(n1, p1), (n2, p2)| p2 <=> p1 }
# Ruby 1.9以前
p fruits.sort{ |(_, p1), (_, p2)| p2 <=> p1 }
#=> [["mango", 800], ["pineapple", 500], ["apple", 200]]
# Ruby 2.0以降
p fruits.sort{ |(_n1, p1), (_n2, p2)| p2 <=> p1 }
#=> [["mango", 800], ["pineapple", 500], ["apple", 200]]
演算子
||=
通称「nilガード」などと呼ばれ、初期化イディオムとして使われます。
# fooが偽なので右辺が代入される
foo ||= true
foo
# => true
# fooが代入されて真となるので、右辺が代入されない
foo ||= 'hoge'
foo
# => true
def initialize(name, age)
@name = name
@age = age
end
def <=>(other)
@age <=> other.age
end
end
taro = Human.new("太郎", 25)
jiro = Human.new("次郎", 18)
p taro < jiro
# => false
p taro > jiro
# => true
p taro <=> jiro
# 1
# 通常のlambdaの書き方
bar = lambda { |x| x + x }
bar.call 5 # => 10
class Comment < ActiveRecord::Base
scope :created_before, ->(date) { where("created_at < ?", date) }
end
module Constants
AgeStart = 0
AgeEnd = 99
end
class Customer < ActiveRecord::Base
age_start = Constants::AgeStart #=> 0
age_end = Constants::AgeEnd #=> 99
validates :age, :inclusion => { :in => age_start..age_end }
end
::Foo
# => "foo"
# オブジェクトがnilならnilが返る
something_nil&.profile&.sns&.twitter
#=> nil
# nilでないオブジェクトでも存在しないメソッドを呼ぶとNoMethodError
building&.profile&.sns&.twitter
#=> NoMethodError: undefined method `profile?' for "building":Building
!!
すべてをtrueかfalseにします。
nilではなく、必ずfalseで返したい場合などに使います。
組み込み変数
$で始まる変数はグローバル変数ですが、その中でも特別な役割が与えられている特殊な変数が「組み込み変数」です。
sample.rb
class Sample
def show_file_name
puts "This file name is #{$0}"
end
end
Sample.new.show_file_name
ENV
Rubyで標準で用意されている組み込み定数がいくつかありますが、Railsの開発でよく用いるのはENV(エンブ)のみです。
ENVは環境変数を表すオブジェクトで、ENV['KEY_NAME']のような形でKEY_NAMEと合致する値を取り出すことができます。
Railsではsecret.ymlの中でENV["SECRET_KEY_BASE"]のように環境変数を取り出しています。
development:
secret_key_base: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
test:
secret_key_base: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
その他記法
%w( )、%i( )、%s( )など
「パーセント記法」と呼ばれ、配列作成などによく使われます。
=>
「ハッシュロケット」と呼ばれ、ハッシュリテラルを書く際にキーと値を区切るものです。
なお、Ruby 1.9以降では別の書き方が出てきて、現在ではそちらが推奨です。ハッシュロケットはできるだけ使わない方ようにしてください。
# Ruby 1.9 以降
{ name: "Alex" }