ジョギング
日課
- (腕立て x 50 + 腹筋 x 50) x 3
体調
- 悪し
- 暑さにやられた感がある
今日のるびぃ ~ REx - Ruby Examination にチャレンジ (38) ~
REx - Ruby Examination の問題を自分なりにアレンジした上で 1 〜 3 問くらいずつ解いていく. 正直言ってかなり難しい. 尚, irb に動作確認環境は以下の通り.
$ ruby --version ruby 2.1.10p492 (2016-04-01 revision 54464) [x86_64-linux] $ irb --version irb 0.9.6(09/06/30)
正規表現
以下のコードを実行するとどうなるか.
p "This is a aPPle"[/[a-z][A-Z].*/]
以下, 解答.
aPPle が表示される
以下, irb にて確認.
irb(main):017:0> p "This is a aPPle"[/[a-z][A-Z].*/] "aPPle" => "aPPle"
以下, 解説より抜粋.
- スラッシュ
/
で囲まれた文字列は正規表現と扱われる - 設問では, 文字列から
String#[]
で正規表現を用いて部分文字列を抜き取る - 設問の正規表現
/[a-z][A-Z].*/
を分解すると以下のような意味となる[a-z]
: 1文字目が小文字英字[A-Z]
: 2文字目が大文字英字.*
: 任意の1文字が0回以上繰り返す
Regexp#match
Regexp#match
を試す.
指定された文字列 str に対して位置 pos から自身が表す正規表現によるマッ チングを行います。マッチした場合には結果を MatchData オブジェクトで返し ます。 マッチしなかった場合 nil を返します。
irb(main):022:0> p "This is a aPPle".match(/[a-z][A-Z].*/) #<MatchData "aPPle"> => #<MatchData "aPPle">
正規表現にマッチした部分文字列だけが必要な場合, 以下のように書くことで取得出来る.
irb(main):023:0> bar = /foo(.*)baz/.match("foobarbaz") => #<MatchData "foobarbaz" 1:"bar"> irb(main):024:0> bar = /foo(.*)baz/.match("foobarbaz").to_a[0] => "foobarbaz" irb(main):025:0> bar = /foo(.*)baz/.match("foobarbaz").to_a[1] => "bar" irb(main):027:0> /(foo)(bar)(baz)/.match("foobarbaz").to_a.values_at(1,2,3) => ["foo", "bar", "baz"]
String#[]
String#[]
を試す.
nth 番目の文字を返します。 nth が負の場合は文字列の末尾から数えます。 つまり、 self.size + nth 番目の文字を返します。 nth が範囲外を指す場合は nil を返します。
irb(main):029:0> 'bar'[-1] => "r" irb(main):030:0> 'bar'[0] => "b" irb(main):031:0> 'bar'[1] => "a" irb(main):032:0> 'bar'[2] => "r"
正規表現 regexp の nth 番目の括弧にマッチする最初の部分文字列を返します。 nth を省略したときや 0 の場合は正規表現がマッチした部分文字列全体を返します。 正規表現が self にマッチしなかった場合や nth に対応する括弧がないときは nil を返します。
このメソッドを実行すると、 マッチ結果に関する情報が組み込み変数 $~ に設定されます。
irb(main):037:0> 'foo bar baz'[/f.o/] => "foo" irb(main):038:0> $~ => #<MatchData "foo"> irb(main):039:0> $~.to_a => ["foo"]
Object クラス
以下のコードを実行するとどうなるか.
class Object CONST = "1" def const_succ CONST.next! end end class Child1 const_succ class << self const_succ end end class Child2 const_succ def initialize const_succ end end Child1.new Child2.new p Object::CONST
以下, 解答.
5 が表示される
以下, irb による確認.
irb(main):001:0> class Object irb(main):002:1> CONST = "1" irb(main):003:1> def const_succ irb(main):004:2> CONST.next! irb(main):005:2> end irb(main):006:1> end => :const_succ irb(main):007:0> irb(main):008:0* class Child1 irb(main):009:1> const_succ irb(main):010:1> class << self irb(main):011:2> const_succ irb(main):012:2> end irb(main):013:1> end => "3" irb(main):014:0> irb(main):015:0* class Child2 irb(main):016:1> const_succ irb(main):017:1> def initialize irb(main):018:2> const_succ irb(main):019:2> end irb(main):020:1> end => :initialize irb(main):021:0> irb(main):022:0* Child1.new => #<Child1:0x0056408aab6190> irb(main):023:0> Child2.new => #<Child2:0x0056408aaae990> irb(main):024:0> irb(main):025:0* p Object::CONST "5" => "5"
以下, 解説より抜粋.
- Object クラスにメソッドを定義すると特異クラスでもそのメソッドを利用することが出来る
Object#const_succ
について, 内部でString#next!
を実行している為, レシーバーの文字列を次の文字列へ進める
以下, クラス定義毎に Object::CONST
の値を確認.
irb(main):001:0> class Object irb(main):002:1> CONST = "1" irb(main):003:1> def const_succ irb(main):004:2> CONST.succ! irb(main):005:2> end irb(main):006:1> end => :const_succ irb(main):007:0> p Object::CONST "1" => "1" irb(main):008:0> class Child1 irb(main):009:1> const_succ irb(main):010:1> class << self irb(main):011:2> const_succ irb(main):012:2> end irb(main):013:1> end => "3" irb(main):014:0> p Object::CONST "3" => "3" irb(main):015:0> class Child2 irb(main):016:1> const_succ irb(main):017:1> def initialize irb(main):018:2> const_succ irb(main):019:2> end irb(main):020:1> end => :initialize irb(main):021:0> p Object::CONS "4" => "4" irb(main):022:0> Child1.new => #<Child1:0x0056352f061778> irb(main):023:0> p Object::CONST "4" => "4" irb(main):026:0> Child2.new => #<Child2:0x0056352ef600b8> irb(main):027:0> p Object::CONST "5" => "5"
また, Object クラスではなく, 任意のクラス (Foo) を定義した場合の挙動を確認.
irb(main):001:0> class Foo irb(main):002:1> CONST = "1" irb(main):003:1> def const_succ irb(main):004:2> CONST.next! irb(main):005:2> end irb(main):006:1> end => :const_succ irb(main):010:0> class Bar irb(main):011:1> class << self irb(main):012:2> const_succ irb(main):013:2> end irb(main):014:1> end NameError: undefined local variable or method `const_succ' for #<Class:Bar> ...
上記のように, 特異メソッドを定義しようとしても例外となる.
フムフム.