LoginSignup
20

More than 5 years have passed since last update.

ruby2.2.0の機能

Last updated at Posted at 2014-12-26

2.2.0のニュースのruby2.1.0からの変更点を見ながらいじって見ようと思います。一部わからなかったのはご勘弁を。

sample.rb
puts RUBY_VERSION #=> 2.2.0

文法上の変更

nil/true/falseがfrozen

sample.rb

puts nil.frozen?
puts true.frozen?
puts false.frozen?
#インスタンス変数が持てない
nil.instance_variable_set(:@a,:a) rescue p $!

ハッシュの記法が追加

sample.rb

x = "X"
hash1 = { "hoge": 1 } #=> {:hoge=>1}
hash2 = { "key#{x}": 2 } #=> {:keyX:2}
puts hash1, hash2

# 旧バージョンでは動作しない
# 【注意】
# puts {x: 1}
# とかは昔から出来なかった。

キーワード引数についてのもろもろ

キーワード引数のデフォルトの値に他のキーワード引数が使えるようになった。ただし、使える引数はその引数より先にあるもののみ。

sample.rb

# キーワード引数
# 指定が全くないとエラー
def hoge(var:)
  p var.inspect
end
hoge rescue $!

下の例は、外ではvarが100になっているけどキーワード引数とかぶったらキーワード引数が優先される。
ただし、デフォルトの値にそのキーワード引数を用いると怒られる。このとき、キーワード引数のところにnilが入っていると思ってその引数のデフォルトの値が決定される。

sample.rb
var = 100
def foo(var: var.class)
  p var.inspect
end
foo(var: 1) # => "1"
foo rescue p $! # => "NilClass"

# 先に出てきているキーワード引数を使うことはできる
# しかし、後に出てくる引数は使えない
def hige(vava:, var: vava + 1)
  p var.inspect
end
hige(vava: 100) # => "101"

def hige2(var: vava + 1, vava: )
  p var.inspect
end
hige2(vava: 1) rescue p $!
# 後に出てくる引数が使えないっていうのは次ようなのが面倒だからなのかな?

def hige3(var: var2, var2: var)
  p [var, var2]
end
hige3 rescue p $!
hige3(var: 11) #=> [11, 11]

コアクラスのメソッドの変更

Binding

sample.rb
def foo(str)
  binding
end
p foo(nil).local_variables
class Hoge
  def foo
    binding
  end
end
x = Hoge.new
p x.foo.receiver == x #=> true
p binding.receiver #=> main
# メタプログラミング向きのお話かな?

Dir

sample.rb
puts Dir.new("./").fileno
#ファイルディスクリプタと聞いてわかる人向け

Enumerable

slice_after

sample.rb
x = Array.new(10){rand(20)}
p x
p x.slice_before(&:even?).to_a
p x.slice_after(&:even?).to_a
p x.slice_when rescue p $!
p x.slice_after{|x|x**2 % 8 == 1}.to_a
p x.slice_when{|x|x**2 % 8 == 1}.to_a
#切り場所が前か後から
#slice_beforeは以前から
#slice_whenはブロック必須

min, max

sample.rb
p (3..15).min(3)
p (1..7).map{|x|x**4 %7}
p (1..7).max_by{|x|x**4 %7}
p (1..7).max_by(4){|x|x**4 %7}
p (1..7).max_by(2){|x|x**4 %7}

引数を取ることができるようになった。
引数の分だけ出力。(.min(3)だと、小さいもの3つを出す)

Float

sample.rb

p 1.0
p 1.0.next_float
p 1.0.prev_float
p 0.0.prev_float
p 0.next_float rescue p $!
# 整数はダメ
p 10.times.inject([0.to_f]){|ar|ar<<ar.last.next_float}

p 1.0 / "5.0e-324".to_f # Infinity(以前からこう)
p 1.0/(0.to_f.next_float) # Infinity

File

sample.rb
puts File.birthtime($0)
puts File.open($0).birthtime
puts File::Stat.new($0).birthtime

GC

sample.rb
p GC.latest_gc_info

なんか情報が出る。そのなかに:stateというキーがある

IO

pipeのためのIO#nonblock_readやIO#nonblock_writeがWindowsでもサポートされたらしい。

Kernel

sample.rb
puts itself #=> main
puts 100.itself #=> 100
x = Object.new
puts x == x.itself
puts x.dup == x.itself

# catchされないthrowは専用のエラーを返す事になった
throw "hoge" rescue p $!

Process

よくわからん

String

sample.rb
s = "がぎぐげご"
p s.unicode_normalized?
p s.encode('UTF8-MAC').unicode_normalized? rescue p $!

Method

カリー化

sample.rb
def f(a,b,c)
  p [c,b,a]
end

p x = method(:f).curry
p y = x.call(1)
y.call(2,3)

カリー化よりメソッドってmethod(symbol)でとれたんだーと思ったり。

Method

super_method

sample.rb
class Foo
  def self.double(m)
    define_method(m) do
      [method(m).super_method.call, method(m).super_method.call]
    end
  end
  double :to_s
end
x = Foo.new 
p x.to_s #2つ表示される

define_methodのときにFooのメソッドを引っ張ってきているように見えるけど、中身は見ていないみたい。

sample.rb
class Method
  alias old_super_method super_method
  def super_method
    puts "#{self}を参照しました"
    old_super_method
  end
end

class OObject
  def initialize
    super
    @m = method(:to_s).super_method
  end
end
x = OObject.new
puts x.to_s # 一回しか「◯◯を・・・」って表示されない

superのときに呼ばれているわけではない?

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
20