初心者がRubyの基礎を覚えたところで他人のコードを読むようになると、*args
や map(&:to_s)
のような謎の記法がでてきます。
この手の記法は名前がわからないとググラビリティが低くなるため、人によってはつまづきとなることが多いようです。
尋ねられることがたまにありますので、この機会にRails開発でよく使われるものを中心にまとめてみます。
引数
*args
変数名の冒頭に*
(アスタリスク)が付いているもので、「可変長引数」または「splat引数」とかいいます。
引数を複数個設定でき、さらにメソッド内部で引数を配列として受け取ることができます。
def splatter(*args)
p args
end
splatter('foo')
# => ['foo']
splatter('foo', 'bar', 'baz')
# => ['foo', 'bar', 'baz']
なお、慣用的にargumentsを表す*args
と名付けられることが多いですけど、ただの変数名なので*hoge
でも何でも大丈夫です。
**opts
**
(アスタリスク2つ)が最初にくると「キーワード引数」といい、メソッド内部にハッシュが渡されるようになります。
オプション設定が必要なメソッドで使われることが多いと思います。
def hello_with_option(msg, **opts)
name = opts[:name]
time = opts[:time] || Time.now
puts "#{msg} #{name}@#{time}"
end
hello_with_option("Hello!", name: "nashirox")
# => Hello! nashirox@2017-02-07 16:58:46 +0900
デフォルト引数で空ハッシュ opts = {}
を設定しても同じことになります。
キーワード引数はRuby2.0から導入されている比較的新し目の文法なので、こっちの書き方もよくみられるように思います。
&block
仮引数(例えばblock)に&
を前置すると、「ブロック引数」となります。
メソッドはこの仮引数を介してブロックを受け取れるようになります。
def this_is_block(&block)
block.call # yield でも同じ
end
this_is_block do
p "This is my block"
end
# => "This is my block"
より詳細には、&
を前置することでブロックをProcオブジェクト(手続きオブジェクト)に変換しています。
&:method_name
map
などブロックで配列の中身を受け取るようなメソッドに、ブロック代わりに&
を前置したメソッド(:method_name
)を渡すことができます。
# 配列の要素をstringにして返す
[1, 2, 3].map(&:to_s)
# => ["1", "2", "3"]
# 上と同じ
[1, 2, 3].map { |i| i.to_s }
# => ["1", "2", "3"]
# 配列内の総和を得る
[1, 2, 3].inject(&:+)
# => 6
なぜこう言ったことができるかについてはProcに関する理解が必要なのでここでは割愛します、調べると色々出てくると思います。
演算子
||=
通称「nilガード」などと呼ばれ、初期化イディオムとして使われます。
左辺がtrueだったら何もせず、falseだったら右辺を代入します。
# 初期化されていない変数の呼び出し
foo
# => NameError: undefined local variable or method `foo' for main:Object
# fooが偽なので右辺が代入される
foo ||= true
foo
# => true
# fooが代入されて真となるので、右辺が代入されない
foo ||= 'hoge'
foo
# => true
以下は全て同じ結果です。
foo = foo || true
foo || (foo = true)
nilガードを使わないと、下記のようなif文になってしまい冗長ですね。
if foo != nil
foo = foo
else
foo = true
end
<=>
人によって(?)は未確認飛行物体のように見えるようで、「宇宙船演算子」や「UFO演算子」と通称されます。
左辺と右辺を比較して、左辺側が大きければ 1
、逆に小さければ -1
を返す。双方等しければ 0
、比較できなければ nil
を返します。
100 <=> 200 # => -1
200 <=> 100 # => 1
200 <=> 200 # => 0
100 <=> '100' # => nil
なお自作クラスで比較演算したい場合、Comparable
モジュールをクラスにインクルードし、<=>
演算子を定義することで可能になります。
class Human
include Comparable
attr_reader :age
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リテラル」や「アロー演算子」と呼ばれます。
# 定義
foo = -> (x) { x + x }
# 呼び出し
foo[5] # => 10
foo.(5) # => 10
foo.call 5 # => 10
# 通常のlambdaの書き方
bar = lambda { |x| x + x }
bar.call 5 # => 10
Railsだとモデルのスコープで使われたりしていますね。
class Comment < ActiveRecord::Base
scope :created_before, ->(date) { where("created_at < ?", date) }
end
Hoge::Foo
::
演算子を使うと、あるクラスまたはモジュールで定義された定数を外部から参照することができます。
Railsの定数管理の手法として、initializers下にアプリケーション全体で使う定数を配置する方法などがありますね。
module Constants
AgeStart = 0
AgeEnd = 99
end
Constants
モジュールで登録可能年齢の上限と下限を定義して、モデルで呼び出します。
class Customer < ActiveRecord::Base
start = Constants::AgeStart #=> 0
end = Constants::AgeEnd #=> 99
validates :age, :inclusion => { :in => start..end }
end
なお、左辺無しの::Foo
と書けたりもして、これはトップレベルの定数を呼び出しています。
class Object
# Objectクラスに定数Fooを追加
Foo = 'foo'
end
::Foo
# => "foo"
!!
すべてをtrueかfalseにします。
nilではなく、必ずfalseで返却したい場合などに使います。
(なお、エクスクラメーションマークが一つだと否定演算子ですね)
!!nil #=> false
!!"abc" #=> true
!!false #=> false
どういうところに使うのかと、Railsだと次のよう使い方があるようです。
def logged_in?
!!session[:user_id]
end
呼び方ですが、日本語圏では見当たらず、欧米では「double-bang」や「bang-bang」などと言うようです(初めて知った)。
組み込み変数
$
で始まる変数はグローバル変数ですが、その中でもすでに値が入っている特殊な変数が「組み込み変数」です。
似たような記号が多くて覚えづらいのですが、最低限3つを押さえておけば良いと思います。
$0
現在実行中のRubyスクリプトの名前が入った変数です。
class Sample
def show_file_name
puts "This file name is #{$0}"
end
end
Sample.new.show_file_name
$ ruby sample.rb
# => This file name is sample.rb
$1, $2, $3..$n
最後に成功したパターンマッチでn番目の括弧にマッチした文字列が入っています。
"foo bar baz" =~ /(f\w+)\s(\w+)/
p $1 #=> "foo"
p $2 #=> "bar"
p $3 #=> nil
$&
最後に成功した正規表現のパターンマッチでマッチした文字列が入っています。
"foo bar baz" =~ /(f\w+)\s(\w+)/
p $& #=> "foo bar"
組み込み定数
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( )など
「パーセント記法」と呼ばれ、配列作成などによく使われます。
解説は各所に上がっていますので、詳細は別記事などを参照してください
# %w 文字列配列
fruits = %w(apple orange mango)
# => ['apple', 'orange', 'mango']
# %i シンボル配列
fruits = %i(apple orange mango)
# => [:apple, :orange, :mango]
なお、文字列配列は%記法を用いて書くことが推奨されています。
以上です。なにか足すようなものがあったら追加します。
それではよきRubyライフを!