factoryBotの{ }はどういう挙動になるのか

こんにちは!kossyです!




アウトプットが大事だと頭ではわかっていながら、
AmazonPrimeVideoにどっぷりの正月休みでした、、、笑

もう新年明けて仕事も始まっているので、
気持ちを切り替えて粛々とブログを更新していきます。




さて、今回はRailsのテストでテストデータを簡単に生成できるGem、
factoryBotでファクトリファイルを記述する際に使用する、
{}を使った記法でどういう挙動になるのか、ブログに残してみたいと思います。




ブロックで囲むと、遅延評価される

結論から言うとタイトル通りになります。
これだけでわかれば苦労しないので、もう少し解説します。



遅延評価とは、今回のケース(FactoryBotを使う)で言えば、テストデータを生成する時に評価されると言う意味になります。
ブロック構文を使わないと、rspecの立ち上げ時に評価されますが、
{}を使って値を定義すれば、FactoryBotを使ってインスタンスを生成しようとした時に、
値が評価されます。



それでもわからねぇ()

上記のことを上司から説明されましたが、実際の動きを確認しないと腑に落ちません。


ってことで、コンソールで試してみます。

$ rails c test --sandbox

このコマンドで、テスト環境のコンソールをDBの中身を変更させずにいじることができます。
(正確に言うとexit時にrollbackが走って変更がリセットされる)
別にsandboxいらないんですけどね、、、笑


早速試してみます。

factories

# user.rb

FactoryBot.define do
  factory :user do
    name                  { Faker::Name.name }
    email                 { Faker::Internet.email }
    password              { 'test1234' }
    password_confirmation { 'test1234' }
    role                  { 0 }
    created_at              Time.now # <- ブロック無し
    updated_at             Time.now # <- ブロック無し
  end
end



# review.rb

FactoryBot.define do
  factory :review do
    bookname { 'Perfect Ruby' }
    content  { 'テストだよ' }
    language { 'Ruby' }
    level    { '初級' }
    created_at { Time.now } #<- ブロックあり
    updated_at { Time.now } #<- ブロックあり
    user
  end
end

これでコンソールで試してみます。

$ rails c test --sandbox


# 以下はログ

[1] pry(main)> FactoryBot.create :user
   (0.3ms)  SAVEPOINT active_record_1
  User Exists (0.7ms)  SELECT  1 AS one FROM `users` WHERE `users`.`email` = BINARY 'danellekuhlman@goodwinfay.com' LIMIT 1
  User Exists (0.4ms)  SELECT  1 AS one FROM `users` WHERE `users`.`name` = BINARY '増田 美緒' LIMIT 1
  User Exists (0.5ms)  SELECT  1 AS one FROM `users` WHERE `users`.`email` = BINARY 'danellekuhlman@goodwinfay.com' LIMIT 1
  SQL (0.5ms)  INSERT INTO `users` (`email`, `encrypted_password`, `created_at`, `updated_at`, `name`) VALUES ('danellekuhlman@goodwinfay.com', '$2a$04$cKY02.d3veqIt4Clqc7fA.m1NhAYarMjsEbGxbK9H24urUcyVziQq', '2019-01-07 21:17:31', '2019-01-07 21:17:31', '増田 美緒')
   (0.3ms)  RELEASE SAVEPOINT active_record_1
=> #<User id: 10, email: "danellekuhlman@goodwinfay.com", created_at: "2019-01-07 12:17:31", updated_at: "2019-01-07 12:17:31", name: "増田 美緒", role: "user">
[2] pry(main)> FactoryBot.create :user
   (0.3ms)  SAVEPOINT active_record_1
  User Exists (0.5ms)  SELECT  1 AS one FROM `users` WHERE `users`.`email` = BINARY 'shannonveum@greenfelderbode.biz' LIMIT 1
  User Exists (0.3ms)  SELECT  1 AS one FROM `users` WHERE `users`.`name` = BINARY '林 莉子' LIMIT 1
  User Exists (0.3ms)  SELECT  1 AS one FROM `users` WHERE `users`.`email` = BINARY 'shannonveum@greenfelderbode.biz' LIMIT 1
  SQL (0.7ms)  INSERT INTO `users` (`email`, `encrypted_password`, `created_at`, `updated_at`, `name`) VALUES ('shannonveum@greenfelderbode.biz', '$2a$04$vr6dTtCBjX5ZHfLr1scLQumF.Fe3JbZBPo6Sg8rdcPOVeJ/LZLhOm', '2019-01-07 21:17:31', '2019-01-07 21:17:31', '林 莉子')
   (0.3ms)  RELEASE SAVEPOINT active_record_1
=> #<User id: 11, email: "shannonveum@greenfelderbode.biz", created_at: "2019-01-07 12:17:31", updated_at: "2019-01-07 12:17:31", name: "林 莉子", role: "user">
[3] pry(main)> FactoryBot.create :user
   (0.2ms)  SAVEPOINT active_record_1
  User Exists (0.3ms)  SELECT  1 AS one FROM `users` WHERE `users`.`email` = BINARY 'boyce@corkery.io' LIMIT 1
  User Exists (0.3ms)  SELECT  1 AS one FROM `users` WHERE `users`.`name` = BINARY '藤本 大樹' LIMIT 1
  User Exists (0.3ms)  SELECT  1 AS one FROM `users` WHERE `users`.`email` = BINARY 'boyce@corkery.io' LIMIT 1
  SQL (0.3ms)  INSERT INTO `users` (`email`, `encrypted_password`, `created_at`, `updated_at`, `name`) VALUES ('boyce@corkery.io', '$2a$04$DLgUxLniJfVlU9d/0ZtF/ev1W3q6yzXn.C85OMB5wwKytp8R6sPoe', '2019-01-07 21:17:31', '2019-01-07 21:17:31', '藤本 大樹')
   (0.2ms)  RELEASE SAVEPOINT active_record_1
=> #<User id: 12, email: "boyce@corkery.io", created_at: "2019-01-07 12:17:31", updated_at: "2019-01-07 12:17:31", name: "藤本 大樹", role: "user">

注目してほしいのは、created_atの値です。
どのレコードも、'2019-01-07 21:17:31'で作成されています。

次はreviewの方をコンソールで試します。

$ rails c test --sandbox

[4] pry(main)> FactoryBot.create :review
   (0.6ms)  SAVEPOINT active_record_1
  User Exists (1.2ms)  SELECT  1 AS one FROM `users` WHERE `users`.`email` = BINARY 'zoila@hane.io' LIMIT 1
  User Exists (0.5ms)  SELECT  1 AS one FROM `users` WHERE `users`.`name` = BINARY '杉山 大地' LIMIT 1
  User Exists (0.4ms)  SELECT  1 AS one FROM `users` WHERE `users`.`email` = BINARY 'zoila@hane.io' LIMIT 1
  SQL (0.5ms)  INSERT INTO `users` (`email`, `encrypted_password`, `created_at`, `updated_at`, `name`) VALUES ('zoila@hane.io', '$2a$04$NGsicKSVqrz0I2CfikbozuLLcAZGlgYkiQmLu0dzzj2uKXOjKE/Vu', '2019-01-07 21:17:31', '2019-01-07 21:17:31', '杉山 大地')
   (0.2ms)  RELEASE SAVEPOINT active_record_1
   (0.3ms)  SAVEPOINT active_record_1
  SQL (30.9ms)  INSERT INTO `reviews` (`user_id`, `bookname`, `content`, `language`, `level`, `created_at`, `updated_at`) VALUES (13, 'Perfect Ruby', 'テストだよ', 'Ruby', '初級', '2019-01-07 21:24:12', '2019-01-07 21:24:12')
   (0.2ms)  RELEASE SAVEPOINT active_record_1
=> #<Review:0x00007fc5afcfaf18
 id: 3,
 user_id: 13,
 bookname: "Perfect Ruby",
 content: "テストだよ",
 language: "Ruby",
 level: "初級",
 created_at: Mon, 07 Jan 2019 21:24:12 JST +09:00,
 updated_at: Mon, 07 Jan 2019 21:24:12 JST +09:00,
 image: nil>
[5] pry(main)> FactoryBot.create :review
   (0.3ms)  SAVEPOINT active_record_1
  User Exists (0.6ms)  SELECT  1 AS one FROM `users` WHERE `users`.`email` = BINARY 'bev@toy.name' LIMIT 1
  User Exists (0.4ms)  SELECT  1 AS one FROM `users` WHERE `users`.`name` = BINARY '前田 杏' LIMIT 1
  User Exists (0.4ms)  SELECT  1 AS one FROM `users` WHERE `users`.`email` = BINARY 'bev@toy.name' LIMIT 1
  SQL (0.4ms)  INSERT INTO `users` (`email`, `encrypted_password`, `created_at`, `updated_at`, `name`) VALUES ('bev@toy.name', '$2a$04$jWBf1xZ3Mq3frPFPZwPrfeTAtnxbL2r1byrkAN2VfurltZppKtVrK', '2019-01-07 21:17:31', '2019-01-07 21:17:31', '前田 杏')
   (0.3ms)  RELEASE SAVEPOINT active_record_1
   (0.2ms)  SAVEPOINT active_record_1
  SQL (0.5ms)  INSERT INTO `reviews` (`user_id`, `bookname`, `content`, `language`, `level`, `created_at`, `updated_at`) VALUES (14, 'Perfect Ruby', 'テストだよ', 'Ruby', '初級', '2019-01-07 21:24:19', '2019-01-07 21:24:19')
   (0.2ms)  RELEASE SAVEPOINT active_record_1
=> #<Review:0x00007fc5b51029a8
 id: 4,
 user_id: 14,
 bookname: "Perfect Ruby",
 content: "テストだよ",
 language: "Ruby",
 level: "初級",
 created_at: Mon, 07 Jan 2019 21:24:19 JST +09:00,
 updated_at: Mon, 07 Jan 2019 21:24:19 JST +09:00,
 image: nil>
[6] pry(main)> FactoryBot.create :review
   (0.2ms)  SAVEPOINT active_record_1
  User Exists (0.4ms)  SELECT  1 AS one FROM `users` WHERE `users`.`email` = BINARY 'ferdinandyundt@satterfieldhalvorson.com' LIMIT 1
  User Exists (0.3ms)  SELECT  1 AS one FROM `users` WHERE `users`.`name` = BINARY '野口 悠' LIMIT 1
  User Exists (0.3ms)  SELECT  1 AS one FROM `users` WHERE `users`.`email` = BINARY 'ferdinandyundt@satterfieldhalvorson.com' LIMIT 1
  SQL (0.4ms)  INSERT INTO `users` (`email`, `encrypted_password`, `created_at`, `updated_at`, `name`) VALUES ('ferdinandyundt@satterfieldhalvorson.com', '$2a$04$WovEde/7WJawJLYJBkqbRuElisVtJR.yW96Rqvk95AUqsRp1HBfq6', '2019-01-07 21:17:31', '2019-01-07 21:17:31', '野口 悠')
   (0.2ms)  RELEASE SAVEPOINT active_record_1
   (0.2ms)  SAVEPOINT active_record_1
  SQL (0.4ms)  INSERT INTO `reviews` (`user_id`, `bookname`, `content`, `language`, `level`, `created_at`, `updated_at`) VALUES (15, 'Perfect Ruby', 'テストだよ', 'Ruby', '初級', '2019-01-07 21:24:21', '2019-01-07 21:24:21')
   (0.2ms)  RELEASE SAVEPOINT active_record_1
=> #<Review:0x00007fc5b3e954f0
 id: 5,
 user_id: 15,
 bookname: "Perfect Ruby",
 content: "テストだよ",
 language: "Ruby",
 level: "初級",
 created_at: Mon, 07 Jan 2019 21:24:21 JST +09:00,
 updated_at: Mon, 07 Jan 2019 21:24:21 JST +09:00,
 image: nil>

めっちゃ長いですが、見るべき所はこちらもcreated_atだけです。

'2019-01-07 21:24:12'
'2019-01-07 21:24:19'
'2019-01-07 21:24:21'

3つのレコード全ての値が異なっています。







これが遅延評価だ!!

ブロックで囲まなかった方は、コンソールの立ち上げ時にfactoryの値が評価されて(Time.nowの値が決まる)いますが、
ブロックで囲ったTime.nowの方は、factoryを呼び出す(レコードを生成する)たびにTime.nowが行われているのがわかります。



コンソールで試すと理解が進みますね。



参考にさせていただいた記事
RSpecにおけるFactoryGirlの使い方まとめ - Qiita
FactoryGirlチートシート - Qiita

ng new でプロジェクト名に_(アンダースコア)は使えないという罠

こんにちは!kossyです!




本日気になったニュースはこちら
headlines.yahoo.co.jp

iphoneめっちゃ高いですよね。
円高だった頃はまだ安かったイメージですけど、
Zenfoneとかその他ローエンド?なAndroid端末とはとんでもない価格差になった感があります。

もう一回円高になれば多少は安くなるかもしれないですけど、
その頃には不景気になってそうですね、、、










さて、今回はangular cliで使えるコマンドである、
ng new での新規プロジェクト作成の際に、_(アンダースコア)は使えないという知見を得ましたので、
ブログに残しておこうかと思います。




エラーログ
このコマンドを実行したら、

$ ng new pr_angular

こんなエラーログが。

Schematic input does not validate against the Schema: {"name":"pr_angular","version":"7.1.3","routing":false,"style":"css"}
Errors:

  Data path ".name" should match format "html-selector".


Schematic input does not validate against the Schema
でグーグル検索しても英語のドキュメントしか出てこなかったので仕方なく読む。

すると、


Just got the same error with an underscore in the project name.

というコメントを発見。
"私もプロジェクト名に_を使ったら同じエラーに遭遇したよ"
というような感じでしょう。

pr_angularとしていたのを、
pr-angularとしたら、
無事に新規プロジェクトを作成できました。



グーグル翻訳最高ですね。

TLSプロトコルの解説スライド

こんにちは!kossyです!




12月からエンジニアとして働き出して、業務で今まで全く使っていない技術を使うことになったので、
基礎を固める学習に時間を取られブログを全く更新できていませんでした、、、




この土日はゆっくりできそうなので、ブログも更新したいと思います。




さて、今回はTLSプロトコルに関して詳しく解説されているスライドを見つけたため、
ご紹介できればと思います。




speakerdeck.com

ほんとに通信面の知識には疎いので、
業務に慣れてきたら通信周りを鍛えたいです、、、

Consoleでモデルの出力を整形するGem 'Hirb'

こんにちは!kossyです!




本日気になったニュースはこちら
headlines.yahoo.co.jp

解雇規制の緩和が行われるまでは、共存の状態が続くのではないでしょうか。
もっとも、その領域に口を出す政治家が現れるかはわかりませんが、、、









さて、今回はRailsのREPL環境であるpry上で、モデルの出力を整形して
表示してくれるGem'Hirb'の導入方法について、
ブログに残してみたいと思います。




環境
Rails 5.1.6
Ruby 2.5.1
MacOS Mojave





gemの導入

hirbとhirb-unicodeというgemを導入します。

Gemfile

group :development do
  gem 'hirb'
  gem 'hirb-unicode'
end

irbを使用する場合はこのままでも使えるのですが、
pryを導入している場合はこのままでは使えないので、
.pryrcというファイルをアプリケーションファイル直下に作成します。





.pryrcの作成

.pryrc

begin
  require 'hirb'
rescue LoadError
  # Missing goodies, bummer
end

if defined? Hirb
  # Slightly dirty hack to fully support in-session Hirb.disable/enable toggling
  Hirb::View.instance_eval do
    def enable_output_method
      @output_method = true
      @old_print = Pry.config.print
      Pry.config.print = proc do |*args|
        Hirb::View.view_or_page_output(args[1]) || @old_print.call(*args)
      end
    end

    def disable_output_method
      Pry.config.print = @old_print
      @output_method = nil
    end
  end

  Hirb.enable
end

これでconsole上でモデルの出力を整形できます。
こんな感じで出力されます。

f:id:kossy-web-engineer:20181202122210p:plain

localhost:3000/rails/info でルーティング一覧が見られる

こんにちは!kossyです!




本日気になったニュースはこちら
www.tv-tokyo.co.jp

本日のことでもないしニュースでもないですが(笑)

ビニールハウスってデッドスペースが多いですし、
野菜を縦に育てるという発想が素晴らしいですね。

野菜を一年中安価で提供できるのはいいと思いますが、
このサービスを利用した事業者が増えすぎて、野菜市場が下落してしまい、
事業が立ち行かなくなってしまう危険性はあると思っています。










さて、今回は、記事にするほどでもないかもしれませんが(というかいつもそうかもしれない笑)、
rails routesに換わるルーティングの確認の仕方を見つけたので、
ブログに残してみたいと思います。




環境
Rails 5.1.6
Ruby 2.5.1
MacOS Mojave





localhost:3000/rails/infoにブラウザからアクセスするとルーティングの一覧が表示される

見出しで話が完結するのですが、開発環境でlocalhost:3000/rails/infoにアクセスすると、
f:id:kossy-web-engineer:20181130172804p:plain

こんな感じで出力されます。

path表示とurl表示を切り替える機能と、
マッチするURLをソートできる機能が搭載されています。

URLはlocalhost:3000/rails/info/routesなのですが、
localhost:3000/rails/infoにアクセスすると、自動的にroutesにリダイレクトされます。



今までターミナルでrails routesしていたのですが、
もういらないですね。

RSpecでdeviseを使う方法

こんにちは!kossyです!




本日気になったニュースはこちら
dev.classmethod.jp

サーバレスについて少し調べてみましたが、よくわかりませんでした、、、
オンプレやレンタルサーバとも違うみたいですね。

このサービスを用いることで、オンプレやレンタルサーバと比較して
ランニングコストを抑えることができると仮定するならば、
今後はクラウドサーバー環境構築のノウハウを蓄積するよりも、
こちらの技術のノウハウを貯めた方がいいかもしれません。











さて、今回はRailsのテストフレームワークであるRSpecで認証系のGemとして有名なdeviseを使う方法を
ブログに残してみたいと思います。



環境
Rails 5.1.6
Ruby 2.5.1
RSpec 3.8.0
MacOS Mojave





マクロファイルの作成

controller_macros.rbという名前でファイルを作成し、loginメソッドを定義します。
macrosってなんだ?と思いましたが、
マクロ(ヘルパーメソッド)を定義してフィーチャースペックのユーザー切替えを楽に行う - Qiita

こちらによると、マクロ = ヘルパーメソッド
という認識で間違いなさそうです。

以下参考コードです。

spec/support/controller_macros.rb

module ControllerMacros
  def login(user)
    @request.env["devise.mapping"] = Devise.mappings[:user]
    sign_in user
  end
end


マクロファイルの読み込み

次にmacrosファイルを読み込む記述をします。
include以降の記述でdeviseとmacrosを読み込む処理を記述しています。

spec/rails_helper.rb

RSpec.configure do |config|
  Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
  config.include Devise::Test::ControllerHelpers, type: :controller
  config.include ControllerMacros, type: :controller
end

これでRSpec内でdeviseを使うことができます。





参考にさせていただいたサイト
rspecのテスト環境でdeviseにログインする方法【rails】 - Qiita
マクロ(ヘルパーメソッド)を定義してフィーチャースペックのユーザー切替えを楽に行う - Qiita

Railsにおけるturbolinksの無効化の手順

こんにちは!kossyです!




本日気になったニュースはこちら
aws.amazon.com

AWSで提供されているDynamoDBにトランザクション機能が追加されるそうです。
が、当方インフラ面には疎いので、何がすごいのかわかりません、、、
他の方の意見を引用すると、


今まで、DynamoDBとRDBMSの違いを説明するときは、トランザクション対応しているかどうかと発言していましたが、
だんだん優劣の説明が難しくなってきましたw。特に最近の立て続けのアップデートはかなり強力でした。
ネイティブでの暗号化、ポイントインタイムリカバリ対応、トリガー、グローバルテーブル、
KMS対応、ローカルテスト、アクセラレータ、そして、今回のトランザクション対応によって、
多くのデータベースの移行先や、新規サービスのデータベース基盤として、DynamoDBを検討できるのではないでしょうか。
とくに、サーバーレスとかIoTのバックエンドとしてDynamoDBは無くてはならない存在です。
今後の更なる進化にも期待したいですね。

出典: DynamoDBのトランザクションについてFAQ形式で答えてみる #reinvent | DevelopersIO

とのことでした。
トランザクションに対応したことで、DynamoDB一択、ということになっていくのでしょうか。










さて、今回はRailsで標準で組み込まれている、
turbolinksを無効化する手順について、ブログに残してみたいと思います。




そもそもturbolinksってなにしてくれてるの?

Turbolinksはリンクを生成する要素であるa要素のクリックをフックにして、
移動した先のページをAjaxで取得します。

その後、取得ページのデータが遷移前のページと同じものがあれば再利用し、
title・body要素を置き換えて表示します。
データを再利用するので、アプリケーションの速度向上などのパフォーマンスの向上を
させることができます。

Railsと一緒に使われるイメージがあるTurbolinksですが、
iOSやAndoroid環境でも使用することができます。
github.com




本題

回り道をしてしまいましたが、これからTurbolinksの無効化手順を説明します。


まずはGemfileからTurbolinksを削除します。

gem 'turbolinks', '~> 5'  # この行を削除

bundle updateします。

$ bundle update

次に、application.jsのTurbolinksをrequireしている部分を削除します。

//= require turbolinks  # この行を削除

そして、レイアウトファイルでTurbolinksを読み込んでいる部分を削除します。

# この2行を削除

= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload'
= javascript_include_tag 'application', 'data-turbolinks-track': 'reload'

これでTurbolinksを削除できます。

SSH通信の概要

こんにちは!kossyです!




本日気になったニュースはこちら
jp.techcrunch.com

太っ腹ですね。
Progateをはじめとした各種プログラミング学習サービスの充実度は
本当に素晴らしいもので、初学者向けの学習環境の整備はめちゃめちゃ進んでいる印象です。
ただ、今まではWeb系コンテンツの充実度ばかりが進行していた気がしますので、
今回のAmazonの発表でWeb系以外のコンテンツもどんどん充実してほしいなと思います。










さて、今回はSSH通信の概要についてブログに残してみたいと思います。




SSHとは?

暗号や認証技術を用いて、セキュアにリモートコンピュータと通信を行うための通信プロトコルのことです。
プロトコルとは、大雑把に言ってしまうと、通信を行う際の決め事、です。

どんなメリットがあるのか

きちんとセキュアにSSH通信が行われていれば、以下のようなメリットが得られます。

①通信が盗聴される危険性を回避できる
②バックアップを取りたい時に、サーバ上で圧縮して、ファイルを一括ダウンロードできるので、アップロード・ダウンロード時に
 時間短縮ができる
③リモート(遠隔)サーバ上でファイルの操作や編集が安全にできる


より詳しく

SSH通信が中で何を行なっているか、とても詳しく解説してくれています。
qiita.com

実際の設定までカバーされています。
qiita.com



通信周りの知識がまだまだ足りていないと感じています。。。

Rubyの X || = y みたいなコードの読み方

こんにちは!kossyです!




本日気になったニュースはこちら
thebridge.jp

いいサービスだな、と思ったら既に類似のビジネスが走っているのですね、、、
どんだけこの界隈に疎いんだよ自分、、、

しかしクラウドファンディングに成功してニュースとして取り上げてくれるのはいいですね。
まだサービスがローンチされてない中でこのようにメディアに取り上げてくれるのは、
ある程度の広告効果が期待できそうです。

サービスの提供開始前の広告戦略として参考になるかも。









さて、今回はRubyにおける自己代入のイディオムである、|| = の読み方について、
ブログに残して見たいと思います。





環境
Ruby 2.5.1




Ruby熟練者がよく書くらしい

最初見たときはなんじゃこりゃ、と思いましたが。
Rubyの熟練者の方がよく使うらしいです。
Railsチュートリアルにもこのイディオムは登場してますね。


|| = の解読

端的にまとめると、
「左辺の値がnilであれば、右辺の値を左辺に代入する。もし左辺に値が存在していれば、
右辺の値は評価されない」
と言うイディオムになります。

例えば、

@current_user ||= User.find_by(id: user.id)

というコードがあるとすれば、
「@current_userの値がnilであれば、Userモデルの中のidがuser.idであるレコードを検索して、
@current_userに値を代入する」
という流れになります。

使いこなせれば結構便利ですね。

ミュータブルとイミュータブル

こんにちは!kossyです!




本日気になったニュースはこちら
news.yahoo.co.jp

そこまでやるか、って感じですね、、、
インターネットや検索エンジンが人々の生活を豊かにしたのは間違いないですし、
規制の深化でテクノロジーの進歩が阻害されるようなことがあってはいけないと思ってます。











プログラミングを学んでいると、毎日必ず知らない単語に出会うのですが、
今日もご多聞に漏れずミュータブルとイミュータブルという単語に出会ってしまいました。

今回はミュータブルとイミュータブルとはなんぞや、ということで
ブログに残しておこうかと思います。



ミュータブルとは?

英語で書くとmutableって書くみたいですね。
bleで語尾が終わっていると(availableとかvariableとか)、「〜できる」とか「〜しやすい」って意味になります。
mutableも他のbleで終わる単語と同様に、「可変の」とか、「変更可能な」等の意味を持っています。

プログラミングの世界では、「破壊的な変更ができる」という意味で使われているみたいです。
Rubyで言うと!マークが付いているメソッドが適用できるってことですね。

例えば、Stringクラスはデフォルトでミュータブルなので、!が付いたメソッドを乱用していると、
意図せずバグを起こすということが起き得ます。

イミュータブルとは?

英語って(と言うか言語って)便利で、一つ単語を覚えてしまうと、
覚えようと思えば対義語や類義語、活用形なんかもすんなり覚えられちゃいます。

イミュータブル(immutable)もmutableと対を成しており、
「不変な」とか「変更不可の」等の訳し方をするみたいです。



余談ですが、im-とかin-で始まる単語は基本的に否定の接頭辞として使われてまして、例えば、
「immposible(不可能)」とか、incredible(信じられない)とかです。

immposibleの対義語はpossibleで、incredibleはcredibleですね。ちなみにcredibleの名詞形はcredit(信用)です。
こんな感じで一つ単語を覚えてしまうと枝のように広がることができるのが面白いですね。



話が逸れてしまいました。
プログラミングの世界では、immutableのことを、「破壊的変更が適用できない」という意味で用いられるみたいです。

Rubyではimmutableなクラスや値がいくつかあって、
・IntegerやFloat
・Symbol
・True/FlaseClass
Nil
等が有ります。



まぁ、「ミュータブルだから〜」とか言われたら、
「あぁ、ここの値変更できるのね」

「イミュータブルだから〜」だったら、
「変更できないのね、freezeすんのかな」

とか思っとけば良さそうです。