LoginSignup
1
2

More than 3 years have passed since last update.

マジックナンバーとrailsにおける定数管理gem "config"

Last updated at Posted at 2021-03-02

この記事の目的

開発中に「マジックナンバー」と言う聞き慣れない(恥ずかしながら)言葉を耳にし、その意味と問題点を調べたのでまとめました。また、Railsにおける「マジックナンバー」への対応策の一つを紹介したいと思います。

この記事で以下のことが分かると思います。

  • マジックナンバーとは何か
  • 開発におけるマジックナンバーの問題点
  • その解決策の一つであるrailsのgem "config"の扱い方

1. マジックナンバーとは

マジックナンバーとは、ハードコーディングされた数値のことです。

ハードコーディングとは、固有名詞・固有値をソースコード内に直接埋め込んだコードのことです。
ソースコードとは、開発者がコーディングしているファイルの内容のことです(index.html, stylesheet.cssなど大体そうかと)。

ハードコードの中でも数値のことを、プログラミングにおいて「マジックナンバー」と呼びます。

index.html.erb

# ハードコードの例
<li>
  <p>山田太郎<p>
  <p><span>23</span>歳です</p> # 23がマジックナンバー
</li>
<li>
  <p>田中花子</p>
  <p><span>73</span>歳です</p> # 73がマジックナンバー
</li>
:

上記はSNSにおけるユーザー一覧の例です。恐らく、こんな直接的な書き方はしないと思います。
一般にマジックナンバーはNGとされています(そもそもハードコードがNGなのかな...)。
その理由を次に説明します。

2. マジックナンバーが何故いけないのか

一般にマジックナンバーは、コーディングの際に避けるべきだ、と言われています。その主な理由は3つだと思われます。

  1. 数字だけ見ても何を意味しているか分からない[可読性が低い]
  2. 変更する場合は全てのマジックナンバーが利用されている場所を変更する必要がある [保守性が低い]
  3. セキュリティの安全性が下がる[脆弱性を生む]

3つの理由の説明はその他のサイトでも説明されていると思います。ここでは、少し具体的なマジックナンバーを使ってしまいそうな例を提示してみます(実体験)。

products_controller.rb
def show
  @product = Spree::Product.find(params[:id])
  @related_products = @product.related_products(4) # マジックナンバー
end

この4という数値が何を意味しているか、このコードを見ただけでは分かりません。
これは下の画像における表示個数の個数を表します。このように、実際の機能に対してコードの意味が伝わりにくくなってしまうのがマジックナンバーの良くない点です。
これ以降では、Railsにおけるマジックナンバーに関する対応策であるconfigと言うgemの扱いを簡単に紹介したいと思います。

[画像挿入]

3. Railsにおける定数管理のgem "config"

以下で具体的な使い方は説明しますが、このgemのいいところは以下の2つだと思います

  • 定数の意味をソースコード内で表現できる
  • 一箇所で定数を管理できる

これがリソースです。
rubyconfig/config

gem "config"は、定数管理を指定のYAMLファイルを用いて一箇所で行う為のgemです。場合によっては環境毎に(development, production, test)定数の値を変更することもできます。
ここでは、簡単な方法を一つ紹介し、先程の例を解決したいと思います。

4. gem "config"の使い方

ここでは最も簡単だと考えられる、一つのファイルで定数を管理する方法を示します。
その場合config/settings.ymlのみ書き込むことで定数管理を実現します。

(1) gem "config"の準備

Gemfile
gem "config"
Terminal
$ bundle install
$ rails g config:install
            create  config/initializers/config.rb
      create  config/settings.yml
      create  config/settings.local.yml
      create  config/settings
      create  config/settings/development.yml
      create  config/settings/production.yml
      create  config/settings/test.yml
      append  .gitignore

以下のようにファイルが追加されます(自動的に.gitignoreに追加されていました)。

(2) 定数を管理する

configでは、木構造のように定数を管理します。
今回は「商品の個数」の中で、「上限の数値」「テストの際の数値」といった定数を定義します。(このように記載することで、先程の例を解決します)

config/settings.yml
products_count:
  max_count: 4
  test_count: 10

このファイルにて定数の管理を、一括で扱います。また、定数への意味付けも可能になります
[可読性上がる]。

(3) - 1 定数を取り出す

定数は以下のように記載することで取り出すことができます。

Terminal
$ rails c
[1] pry(main)> Settings.products_count.max_count
=> 4
[2] pry(main)> Settings.products_count.test_count
=> 10

設定に応じてSetteings. ~ .~の~部分を置き換えることで、定数を取り出すことが可能になります。

(3) - 2 定数を取り出す(ファイル内で)

以上を参考に先程の例を、このように解決することができます。

products_controller.rb
def show
  @product = Spree::Product.find(params[:id])
  @related_products = @product.related_products(Settings.products_count[:max_count])
end

マジックナンバーを比べていた時に比べ、可読性が少しは上がります(恐らく)。

以上です。この記事が少しでも参考になるといいな、と思います。

余談

マジックナンバーには、エンジニアの方にコードレビューして頂いた際に出会いました。「実装要件を満たした」と思った自分に対して、予想のできない指摘が飛んできました。実務の世界では当たり前のことができていない、本当にまだまだなのだな、という実感を沸いた経験でした。

リソース

以下を参考にさせて頂きました

https://wa3.i-3-i.info/word12868.html

https://qiita.com/RyoheiHashimoto/items/38ec132bd2852238295e

https://it-biz.online/it-skills/hard-coding/

また、gem "config"に関しましてはその他多くの説明が存在しますので、詳細はそちらを参考にすると実装が捗るかと思います。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2