Ruby Gold 3を受ける
2.xは持っているが 日曜プログラマーでRubyは業務効率化くらいでしか使ってないので 知識をアップデートする。
要項は以下
実行環境
- 組み込み変数/定数
文法
オブジェクト指向
- メソッドの詳細
- メソッドの可視性
- クラスの詳細
- クラスの継承
- モジュールの詳細
- Module#prepend
- Refinements
メタプログラミング
- eval、define_method、instance_variable_get等
組み込みライブラリ
- よく使用されるクラス、モジュール
- (Object、Module、Kernel、Enumerable、Comparable等)
- 数値
- 正規表現
- Proc
- Enumerator
標準添付ライブラリ
- time、date、singleton、forwardable等
Ruby %記法
%q, %Q, % コーテーションをエスケープしてくれる。%Q, %は式展開あり
%q(ダブルコーテーションは"と書きます) #=> "ダブルコーテーションは\"と書きます"
%w,% W 配列。%Wは式展開あり
%w(aa bb cc) #=> ["aa", "bb", "cc"]
%i, %I シンボル配列。%I は式展開あり
%i(aa bb cc) #=> [:aa, :bb, :cc]
%s シンボル
%s(hogehoge) #=> :hogehoge
%x コマンド
%x(ruby -v) #=> ruby 2.1.5
%r 正規表現
str = "hoge" %r("bar/fuga/#{str}) #=> /"bar\/fuga\/hoge/
Ruby 古いメソッドを呼び出された場合
古いメソッドを警告を出しながらも実行する方法
module Deprecator def deprecate(old_method, new_method) define_method(old_method) do |*args,&block| warn "Warning: #{old_method} is deprecated. Use #{new_method}()" __send__(new_method,*args,&block) end end end class A extend Deprecator def new_fuga "hello" end deprecate :old_fuga, :new_fuga end p A.new.old_fuga #=> Warning: old_fuga is deprecated. Use new_fuga()
Ruby 特異メソッドとダックタイピング
特異メソッドはこういった変数に入ったStringオブジェクトにも追加可能 ・オープンクラス ・Refinements これらを作成するほどでもない特定箇所でのメソッド利用の場合は、お手軽にこういうものが使える。 厳密なクラス定義に拠らないところが特徴。 ダックタイピング(walk とquackを振る舞う動物ならそれはもうDuckだろう)という考え方
str = "FUGA" def str.isUpcase? self.upcase == self end p str.isUpcase? #=> true p str.methods.grep(/^is/) #=> [:isUpcase?, :is_a?]
Ruby 無名クラス、クラス定義のもうひとつの形
無名クラス、クラス定義をフラットスコープ
# 変数にクラス定義を代入 c = Class.new(Array) do def my 'Hello!' end end # それでもメソッドはつかえる p c.new.my #=> "Hello!" # cは無名クラス p c.name #=> nil # 定数に代入してみる Myclass = c # cの名前は MyClass p c.name #=> MyClass
Ruby Methodクラス UnboundMethodクラス
Methodオブジェクトは、メソッドを保存でき、callで実行できる
class A def hoge puts 1 end end a = A.new.method(:hoge) a.call #=>
UnboundMethodはメソッドの付け替えが可能 同じクラス、もしくはサブクラスにしかつけかえられない
class C def my_method 88 end end class A end u = C.instance_method(:my_method) p u.bind(C.new).call #=> 88 p u.bind(A.new).call #=> TypeError: bind argument must be an instance of C
- self の instance_methodを指定するとメソッドをUnboundMethodとしてとりだすことができる
モジュールのメソッドを使ってbindする
module M def my_method 88 end end class A end u = M.instance_method(:my_method) p u.bind(A.new).call #=> 88
- 以上が成功するのは、module Mのクラスが、Moduleクラスだから。ClassのsuperclassはModuleだからだとおもう。たぶん。