すでにメンバーの場合は

無料会員登録

GitHubアカウントで登録 Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

登録がまだの方はこちらから

Pikawakaにログイン

GitHubアカウントでログイン Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

Ruby

【Ruby】 定数について学んでみよう。変数との違いは?

ぴっかちゃん
ぴっかちゃん

定数とは、オブジェクトに付ける名札のようなものです。Rubyにおける定数は再代入可能なので、使い方には注意しましょう。

irb | 定数の使用例
1
2
3
4
irb(main):001:0> FOO = "foo"  
=> "foo"
irb(main):002:0> FOO = "fooo!!" # 警告は出るが、再代入されます。
(irb):2: warning: already initialized constant FOO

定数は、変数と違いアルファベット大文字から始まります。
また、定数は再代入することが出来ないと思っている方が多いと思いますが、Rubyにおける定数は再代入できます。(警告は表示される)

定数の役割

定数は変数と同じ役割を持ち、1つのオブジェクトに対し名札をつける役割を持ちます。

基本的に途中で変更しない値は定数で宣言をします。

(例)
・環境変数
・円周率など不変なもの

変数は小文字で名前をつけますが、定数は大文字から始まります。
最初だけ大文字でも宣言できますし、全て大文字でも宣言できます。
どちらかというと全て大文字で宣言することが多いです。

またメソッド内では宣言することができないことも覚えておきましょう。

irb | 変数と定数の定義
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 変数の定義
irb(main):001:0> name = "ぴっかちゃん"
=> "ぴっかちゃん"
irb(main):002:0> puts name
ぴっかちゃん
=> nil

# 定数の定義
irb(main):003:0> Url = "pikawaka.com"
=> "pikawaka.com"
irb(main):004:0> puts Url
pikawaka.com
=> nil

# 定数の定義
irb(main):005:0> URL = "pikawaka.com"
=> "pikawaka.com"
irb(main):006:0> puts URL
pikawaka.com
=> nil

定数は前述した通り、rubyでは再代入できてしまいます。

irb | 定数の再代入
1
2
3
4
5
6
7
8
9
irb(main):001:0> URL = "pikawaka.com"
=> "pikawaka.com"
irb(main):002:0> URL = "yahoo.co.jp"
(irb):2: warning: already initialized constant URL
(irb):1: warning: previous definition of URL was here
=> "yahoo.co.jp"
irb(main):003:0> puts URL
yahoo.co.jp
=> nil

このように警告文は出ますが、再代入されてしまいました。

ですがfreezeメソッドを使うと破壊的メソッドでの変更に関しては再代入を防ぐことができます。

irb | freezeメソッド
1
2
3
4
5
6
rb(main):002:0> STUDENTS = ["ぴっかちゃん"]
=> ["ぴっかちゃん"]
irb(main):001:0> STUDENTS.freeze
=> ["ぴっかちゃん"]
irb(main):002:0> STUDENTS << "pikawaka"
RuntimeError: can't modify frozen Array

このように警告が出て再代入を防ぐことができます。

破壊的メソッドとは?

破壊的メソッドはレシーバ自身(メソッドを使ったオブジェクト)の値を強制的に変更してしまうメソッドです。
例としてレシーバのアルファベットの文字列を大文字に変換するupcaseメソッドupcase!メソッドで確認してみましょう。
!が付いている方が破壊的メソッドになります。

irb | upcaseメソッドの場合
1
2
3
4
5
6
7
irb(main):001:0> name = "pikawaka"
=> "pikawaka"
irb(main):002:0> name.upcase
=> "PIKAWAKA"
irb(main):003:0> puts name
pikawaka
=> nil

このようにレシーバ自身の値は変更されていません。
次にupcase!メソッドの場合です。

irb | upcase!メソッドの場合
1
2
3
4
5
6
7
irb(main):001:0> name = "pikawaka"
=> "pikawaka"
irb(main):002:0> name.upcase!
=> "PIKAWAKA"
irb(main):003:0> puts name
PIKAWAKA
=> nil

このようにレシーバ自身の値が変更されてしまいました。

Rubyでは最後に!が付いているメソッドや配列に関して変更を与えるメソッド(<<メソッドなど)は破壊的メソッドになります。変数も定数も結局は再代入が可能ですが、値が変わらないものであれば定数として宣言しておくとコードの可読性が高まります。

そういった場合は変数よりも定数で定義しておくのが良いでしょう。こちらの参考書では、Rubyについて理解を深めることができます

この記事のまとめ

  • オブジェクトに対し名札をつけるには変数と定数がある
  • rubyの定数は再代入可能なので注意!
  • 定数はメソッド内で宣言することができない