2.2.0のニュースのruby2.1.0からの変更点を見ながらいじって見ようと思います。一部わからなかったのはご勘弁を。
puts RUBY_VERSION #=> 2.2.0
#文法上の変更
##nil/true/falseがfrozen
puts nil.frozen?
puts true.frozen?
puts false.frozen?
#インスタンス変数が持てない
nil.instance_variable_set(:@a,:a) rescue p $!
##ハッシュの記法が追加
x = "X"
hash1 = { "hoge": 1 } #=> {:hoge=>1}
hash2 = { "key#{x}": 2 } #=> {:keyX:2}
puts hash1, hash2
# 旧バージョンでは動作しない
# 【注意】
# puts {x: 1}
# とかは昔から出来なかった。
キーワード引数についてのもろもろ
キーワード引数のデフォルトの値に他のキーワード引数が使えるようになった。ただし、使える引数はその引数より先にあるもののみ。
# キーワード引数
# 指定が全くないとエラー
def hoge(var:)
p var.inspect
end
hoge rescue $!
下の例は、外ではvarが100になっているけどキーワード引数とかぶったらキーワード引数が優先される。
ただし、デフォルトの値にそのキーワード引数を用いると怒られる。このとき、キーワード引数のところにnilが入っていると思ってその引数のデフォルトの値が決定される。
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
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
puts Dir.new("./").fileno
#ファイルディスクリプタと聞いてわかる人向け
##Enumerable
###slice_after
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
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
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
puts File.birthtime($0)
puts File.open($0).birthtime
puts File::Stat.new($0).birthtime
##GC
p GC.latest_gc_info
なんか情報が出る。そのなかに:stateというキーがある
##IO
pipeのためのIO#nonblock_readやIO#nonblock_writeがWindowsでもサポートされたらしい。
##Kernel
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
s = "がぎぐげご"
p s.unicode_normalized?
p s.encode('UTF8-MAC').unicode_normalized? rescue p $!
##Method
###カリー化
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
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のメソッドを引っ張ってきているように見えるけど、中身は見ていないみたい。
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のときに呼ばれているわけではない?