経理からエンジニア転向した人のメモ

元経理マンがエンジニアに転向して現在

Railsでconfig_forを使ったときのsymbolize_keysについてコンソールで確認してみる。

ryomoyr.hatenablog.com

上の記事のとき、config_forの後ろにyamlファイルの値を参照するとき、 シンボルで引っ張ってくるかどうするかみたいなときに、個人的にはシンボルで 引っ張ってあげたほうがわかりやすかった。 なんパターンかあるので、コンソールで確認してみる。

application.rbにどう書いてあるか

  1. config.x.hogehoge = config_for(:test)
  2. config.x.hogehoge = config_for(:test).symbolize_keys
  3. config.x.hogehoge = config_for(:test).deep_symbolize_keys
  4. config.x.hogehoge = ActiveSupport::InheritableOptions.new(Rails.application.config_for(:test))

config.x.preferenceに格納した値をcontrollerで引っ張るときは、Rails.configuration.x.hogehogeで引っ張る。

ちなみに、test.ymlの中身は以下。

default: &default
  hoge_k: hoge_v
  fuga_k: 
    fuga_k_1: fuga_v_1
    fuga_k_2: fuga_v_2
  foo:
    - bar
    - baz

development:
  <<: *default

test:
  <<: *default

production:
  <<: *default

1のとき

> test = Rails.application.config_for(:test)
=> {"hoge_k"=>"hoge_v", "fuga_k"=>{"fuga_k_1"=>"fuga_v_1", "fuga_k_2"=>"fuga_v_2"}, "foo"=>["bar", "baz"]}

> test["hoge_k"]
=> "hoge_v"

> test[:hoge_k]
=> nil

> test.hoge_k
NoMethodError: undefined method `hoge_k' for #<Hash:0x000000000567b3d0>
    from (irb):4

何もつけないときは、
controllerとかではRails.configuration.x.hogehoge["fuga_k"]["fuga_k_1"]fuga_v_2が引っ張れる。

2のとき

symbolize_keysのとき

> test = Rails.application.config_for(:test).symbolize_keys
=> {:hoge_k=>"hoge_v", :fuga_k=>{"fuga_k_1"=>"fuga_v_1", "fuga_k_2"=>"fuga_v_2"}, :foo=>["bar", "baz"]}

> test["hoge_k"]
=> nil

> test[:hoge_k]
=> "hoge_v"

> test.hoge_k
NoMethodError: undefined method `hoge_k' for #<Hash:0x00000000053315f8>
    from (irb):15


> test[:fuga_k]
=> {"fuga_k_1"=>"fuga_v_1", "fuga_k_2"=>"fuga_v_2"}

> test[:fuga_k][:fuga_k_1]
=> nil

1階層目はシンボルで引っ張れるが、2階層以降は
Rails.configuration.x.hogehoge[:fuga_k]["fuga_k_1"] のようにしないとひっぱれない。

3のとき

> test = Rails.application.config_for(:test).deep_symbolize_keys
=> {:hoge_k=>"hoge_v", :fuga_k=>{:fuga_k_1=>"fuga_v_1", :fuga_k_2=>"fuga_v_2"}, :foo=>["bar", "baz"]}

> test[:fuga_k][:fuga_k_1]
=> "fuga_v_1"

これが一番いいのでは。

4のとき

> test = ActiveSupport::InheritableOptions.new(Rails.application.config_for(:test).deep_symbolize_keys) 
=> {}

> test.hoge_k
=> "hoge_v"

> test.fuga_k.fuga_k_1
NoMethodError: undefined method `fuga_k_1' for {:fuga_k_1=>"fuga_v_1", :fuga_k_2=>"fuga_v_2"}:Hash
    from (irb):56

> test.fuga_k[:fuga_k_1]
=> "fuga_v_1"

irb(main):059:0> test.fuga_k["fuga_k_1"]
=> nil

第一階層のみ.で繋げるが、第二階層以降はシンボルで繋がないとだめみたい。。。

ActiveSupport::InheritableOptionsってなんぞや

ActiveSupport::InheritableOptionsはシンボルでなくて、.で繋げる

> test = ActiveSupport::InheritableOptions.new({name: "Bob"})
=> {}

> test.name
=> "Bob"

既存のハッシュを.でつなげる。

ActiveSupport::InheritableOptionsは子クラスで、親クラスの ActiveSupport::OrderedOptionsは新規に作るときにつかうやつ。

> test = ActiveSupport::OrderedOptions.new
=> {}

> test[:name] = "Alice"
=> "Alice"

> test.name
=> "Alice"


> test = ActiveSupport::OrderedOptions.new
=> {}

> test[:human] = {name: "Charlie"}
=> {:name=>"Charlie"}

> test[:human][:name]
=> "Charlie"

> test.human.name
NoMethodError: undefined method `name' for {:name=>"Charlie"}:Hash
    from (irb):68

> test.human[:name]
=> "Charlie"


> test = ActiveSupport::InheritableOptions.new({human: {name: "Bob"}})
=> {}

> test.human.name
NoMethodError: undefined method `name' for {:name=>"Bob"}:Hash
    from (irb):41

> test.human[:name]
=> "Bob"

ソース見ても難しかったのでわからず。

Railsで共通の設定ファイルをもちたいというとき

config_for()を用いると、シンボルでyamlファイルを指定してそこで共通の設定項目を管理できる。

config/application.rb


module Myapp
  class Application < Rails::Application
    config.time_zone = "Tokyo"
    config.i18n.default_locale = :ja
    config.active_record.default_timezone = :local
    config.load_defaults 5.2
    config.generators do |g|
      g.assets false
      g.helper false
    end

    config.x.preference = config_for(:preference).deep_symbolize_keys

  end
end

config.x.preferencepreferenceは任意の値でOK。

Railsガイドに書いてあるとおり、xを挟むことでネストでも参照できる。 Railsアプリを設定する | Rails ガイド

config_for(:preference)とシンボルでpreferenceと指定しているので、
config直下にpreference.ymlを用意してあげる。

config/preference.yml

default: &default
  hoge_k: hoge_v
  fuga_k: 
    fuga_k_1: fuga_v_1
    fuga_k_2: fuga_v_2
  foo:
    - bar
    - baz

development:
  <<: *default

test:
  <<: *default

production:
  <<: *default

controllerで引っ張ってあげたいときは、
Rails.configuration.x.preference[:hoge_k]みたいにしてあげるとhoge_vが引っ張れる。

deep_symbolized_keyssymbolized_keysの違いについてはこちらでまとめる。

ryomoyr.hatenablog.com

Macでwgetでエラーが出ていたのを解消

maxOS High Sierra 10.13.6

簡単なクローラーを体験しようとしてwgetをインストールしようとしたらできなかった。 似たようなエラーはネットで見つかったが、どれもライブラリが若干違っていた。

// インストールしていない場合はHomebrewをインストール。
$ brew --version
Homebrew 1.8.6
Homebrew/homebrew-core (git revision 91f90; last commit 2019-01-08)
Homebrew/homebrew-cask (git revision 366f9; last commit 2019-01-07)

$ brew install wget

$ wget
dyld: Library not loaded: /usr/local/opt/pcre/lib/libpcre.1.dylib
  Referenced from: /usr/local/bin/wget
  Reason: image not found
Abort trap: 6

解決方法

単純にprecライブラリがなかったので、$ brew install precで解決。

$ brew install pcre
==> Downloading https://homebrew.bintray.com/bottles/pcre-8.42.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring pcre-8.42.high_sierra.bottle.tar.gz
🍺  /usr/local/Cellar/pcre/8.42: 204 files, 5.3MB

$ wget
wget: URLがありません
使い方: wget [オプション]... [URL]...

詳しいオプションは `wget --help' を実行してください

使うときは$ wget -O- http://~でダウンロードできる。