blog.waterlow.work

Ruby, Rails, js, etc...

【Ruby】Goldリベンジ今度こそ

【Ruby】Goldリベンジならず…。 - ITの勉強をいろいろやってみたブログ
引き続きruby goldの復習です。

autoloadの読み込むタイミング

requireは1回しか読み込まない、拡張子省略、バイナリOKでloadはその逆でした。じゃあautoloadはどうなるのか?ってところでした。実はautoloadは内部でrequire(loadではない)を呼んでいるらしい。まぎらわしくない!?load呼べよ。間違えたよ。
b.rb

p "req"
class B
  @@c = 0
  def self.in_b
    p 'b'
    @@c += 1
  end
end
autoload :B, './b.rb'
autoload :B, './b.rb'
p B.in_b
p B.in_b
# 実行結果
# "req"
# "b"
# 1
# "b"
# 2

2行書こうが2回呼ぼうがrequireですから重複して呼ぶことはないです。

メソッドの可視性をしれっと変更
class C
  private
  def c
    p 'c'
  end
end

class B < C
  def c
    super
  end
end
B.new.c

ここは素直に考えていいみたい。継承したクラスで何も書かなければデフォルトパブリックになります。というかあくまでメソッド呼び出しは継承の流れをさかのぼってメソッドを探すだけなのね。

ブロックが渡されたかを問うメソッド
def block_sumple
  puts "stand up"

  yield if block_given?
  puts 'sit down'
end
block_sumple
block_sumple {p "hello"}
# 実行結果
# stand up
# sit down
# stand up
# "hello"
# sit down

またマニアックなものが出ました。block?でもhave_block?でもなくblock_given?

オブジェクトとかモジュールとかってマーシャライズできた?

できた!!特異メソッド定義したやつは無理(ただしクラスメソッドはOK)。あとIOとかDirとかThreadとか無理。

<=>でソートするときの昇順、降順

普通にやると昇順になりますね。降順にしたければブロックのなかのxとyを入れ替えよう。

arr = %w(aaaaa eee c dddddddddddd bbb)
p arr.sort
#["aaaaa", "bbb", "c", "dddddddddddd", "eee"]
p arr.sort{|x,y| x.size <=> y.size}
#["c", "eee", "bbb", "aaaaa", "dddddddddddd"]
インスタンス変数の定義場所

これそのまんま出ました。まだまだ頭がメタになっていません…。class << selfはFooの特異クラスを開いてるので、当然3も特異クラスのクラスインスタンス変数なのです。

@val = 0
class A
  @val = 1
  def a
    @val = 2
  end
  class << self
    @val = 3
    def foo
      p @val #=>1
    end
  end
end

class << A
  p @val #=>3
end
その他

__send__はsendのアライアス、__append__、__add__、<@は無し?、<<はオーバーライド可能。

いろいろやってきましたが、RubyGoldはRuby始める前にとりあえず取っとこう的な資格ではありません。かなりマニアックでこれどう動くんだろう?って問題が多数です。普通にプログラムしていたら見過ごしそうなところばかり。(もしかしたら他の言語でオブジェクト指向をしっかりやっていればすんなりなのかもしれませんが。)メタプロしたりライブラリを作ったりというときはこれぐらいわかっといてくれということでしょうか。あとsilverは自然な答えを選べば解けるけど、goldは自然でない答えがあったり、どれが自然なのかわからない問題が多いです。
ここからはパーフェクトRubyとメタプロRubyを地道に読む戦法に戻します。

2回おちたせいで云万円も損しました…。次落ちたら潔く諦めますかね!
受かったらRuby Goldのe-ラーニングシステムでも作りましょう。