この広告は、90日以上更新していないブログに表示しています。
良書やなEffectiveRuby。
moduleDefaultsNETWORKS = ["192.168.1","192.168.2"].freezeenddefhost_addresses(host, networks=Defaults::NETWORKS) networks.map { |net| net <<".#{host}" }end>> host_addresses(1)=> ["192.168.1.1","192.168.2.1"]>>Defaults::NETWORKS=> ["192.168.1.1","192.168.2.1"]# 書き換えられた!
Arrayのfreezeはハマるやつ。
こう書かないとダメ。
moduleDefaultsNETWORKS = ["192.168.1","192.168.2"].map!(&:freeze).freezeend>> host_addresses(2)Traceback (most recent call last):5: from/Users/rochefort/.anyenv/envs/rbenv/versions/2.5.0/bin/irb:11:in`<main>' 4: from (irb):12 3: from (irb):9:in`host_addresses' 2: from (irb):9:in `map'1: from (irb):9:in`block in host_addresses'FrozenError (can't modify frozen String)
以下は、書籍とは異なりますが、こっちの方がわかりやすいと思ったので、Defaults::NETWORKS を例にして見ました。
>>Defaults::NETWORKS=> ["192.168.1","192.168.2"]>>Defaults::NETWORKS ="a"(irb):32:warning: already initialized constantDefaults::NETWORKS(irb):3:warning: previous definition ofNETWORKS was here=>"a"# 再代入できた!
というようにwarningは出るが書き換わります。
これを防ぎたければ、module/class自体をfreezeすれば良い。
>>Defaults.freeze=>Defaults>>Defaults::NETWORKS=> ["192.168.1","192.168.2"]>>Defaults::NETWORKS ="a"Traceback (most recent call last):2: from/Users/trsw/.anyenv/envs/rbenv/versions/2.5.0/bin/irb:11:in`<main>' 1: from (irb):39FrozenError (can't modify frozen Module)
このmodule/classでfreezeさせるのは使ったことなかったけど、これを利用しちゃえばArray#map!(&:freeze).freeze
という書き方なんてしなくても済むのか。
moduleDefaultsNETWORKS = ["192.168.1","192.168.2"]endDefaults.freezedefhost_addresses(host, networks=Defaults::NETWORKS) networks.map { |net| net <<".#{host}" }end>> host_addresses(3)Traceback (most recent call last):5: from/Users/rochefort/.anyenv/envs/rbenv/versions/2.5.0/bin/irb:11:in`<main>' 4: from (irb):58 3: from (irb):55:in`host_addresses' 2: from (irb):55:in `map'1: from (irb):55:in`block in host_addresses'FrozenError (can't modify frozen String)
なるほど、これなら定数用のモジュールを用意して、そこでfreezeしちゃえばいいのね。
まぁでも定数って割と限定的なclass内で利用したいケースの方が多い気がするからケースバイケースかなぁ。
引用をストックしました
引用するにはまずログインしてください
引用をストックできませんでした。再度お試しください
限定公開記事のため引用できません。