VSCodeでPrettierが動かない時にやったこと(フォーマッタの指定)

目次

動作環境

Prettier動かず

Prettierプラグインをインストール、onsaveなどの基本設定を完了し、いざフォーマットをかけようとしたのですが、なぜか動きません。(設定後の再起動なども行いました)

vscode prettier 動作しないでググり以下の項目を確認したのですが、やはり動きませんでした。。😓

  • settings.jsonがプロジェクト(ワークスペース)配下に存在しない
    • グローバルの設定ファイルが参照されるようになっている
  • editor.defaultFormatteresbenp.prettier-vscodeが設定されている
  • prettier.disableLanguagesで弾いていない

やったこと

VSCodeの右下を見ると、何やらエラーになっていそうなマークを発見しました。 👀

こちらをクリックすると、「複数のフォーマッタが存在しており、1つに指定する必要がある」という警告が表示されました。(スクショ撮れませんでした。🙇‍♂️)

警告内部にある「構成」ボタンをクリックするとフォーマッタの指定をするよう言われ、Prettierを選択しました。

するとsettings.jsonに以下の内容が追記され、無事フォーマットできるようになりました!😊👏

"[css]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
}

所感

↑やったことの前に、トップページを参考に手動でsettings.jsonへフォーマット指定してみたのですが、こちらも動かず。

操作結果としては同じに見えるが、何が良くなかったのだろう。。?🤔

Ruby ||演算子の使い方

目次

概要

ある日、以下のようなコードを発見しました。

puts A.hoge || A.piyo || A.fuga

||ifとセットで(or文として)使われるものと思っていたため、||単体でどのような挙動をするのかわかりませんでした。😓

調査する中で知った仕様を、サンプルコードと合わせてまとめていきます!

検証環境

  • ruby 3.1.0p0 (2021-12-25 revision fb4df44d16) [arm64-darwin21]

検証

大まかな仕様

||は左から順に式を評価していきます。

式の結果がtrueの場合は処理が終わり、nilfalseの場合は次(右)の処理へと進みます。

そうです。場合によっては||に含まれる全ての式が評価されるわけではないのです。😳

IF文とセットの場合

まずは、IF文とセットの場合を検証します。

サンプルコード

def main
  puts 'main start'

  if method1 || method2 || method3 then
    puts 'this is true!!!'
  end

  puts 'main end'
end

def method1
  puts 'this is method1'
  false
end

def method2
  puts 'this is method2'
  true
end

def method3
  puts 'this is method3'
  true
end

main

実行結果

サンプルコードを実行すると以下のように出力されます。

main start
this is method1 # method1が実行され、falseが返る
this is method2 # method2が実行され、trueが返る
this is true!!!
main end

# 「this is method3」が出力されない => method3は実行されていない

結果から分かるように、method3が実行されていません。😳

このように、||が連続している場合は左から処理を評価し、trueとなった時点で評価を終了するのです。

||のみの場合

それでは、||のみの場合を見てみましょう。

name, email, age属性を持つUserクラスを用いて検証します。

サンプルコード

def main
  puts 'main start'

  # 全属性を持っている
  user1 = User.new
  user1.name = 'hoge'
  user1.email = 'hoge@example.com'
  user1.age = 21

  # email,ageを持っている
  user2 = User.new
  user2.email = 'piyo@example.com'
  user2.age = 22

  # ageのみ持っている
  user3 = User.new
  user3.age = 23

  # ||のみの式
  puts user1.name || user1.email || user1.age
  puts user2.name || user2.email || user2.age
  puts user3.name || user3.email || user3.age

  puts 'main end'
end

class User
  attr_accessor :name, :email, :age
end

main

実行結果

main start
hoge # user1の結果
piyo@example.com # user2の結果
23 # user3の結果
main end

結果を以下にまとめました。

  • user1の場合
    1. nameが値を持っていたため、hogeが出力された
    2. emailおよびageも値を持っていたが、評価されなかった
  • user2の場合
    1. nameが値を持っていなかったため、次のemailが評価された
    2. emailが値を持っていたため、piyo@example.comが出力された
    3. ageも値を持っていたが、評価されなかった
  • user3の場合
    1. nameが値を持っていなかったため、次のemailが評価された
    2. emailが値を持っていなかったため、次のageが評価された
    3. ageが値を持っていたため、23が出力された

左から順に式が評価され、true(値を持っている)時点で評価を終了していることが分かります。👀

おわり

||の隠された(知らなかっただけ)挙動を知るきっかけとなりました!

挙動を正しく理解し、きれいなコードを書けるよう日々精進します!💪

Rubyデザインパターン備忘録

目次

概要

Rubyデザインパターンまとめに記載されている各デザインパターンの概要をまとめる。

デザインパターンのポイント

GoFデザインパターンには下のプリンシパルがあります。

  • 変わるものを変わらないものから分離する
  • インタフェースに対してプログラミングし、実装に対して行わない
  • 継承より集約
  • 委譲、委譲、委譲
  • 必要になるまで作るな(You Ain’t Gonna Need It./YAGNI)

デザインパターン一覧

アブストラクトファクトリ(Abstract Factory)

  • 矛盾のないオブジェクトの組み合わせを作る

ビルダ (Builder)

  • オブジェクトの生成に大量のコードが必要
  • オブジェクトを作り出すのが難しい
  • オブジェクト生成時に必要なチェックを行いたい

ファクトリメソッド

  • インスタンスの生成をサブクラスに任せるパターンです。
  • インスタンスの生成部分を切り離すことで、結合度を下げて追加・変更・保守を容易にします。

シングルトンパターン(Singleton)

  • 1つだけに限定されたインスタンスを複数のオブジェクト内で共有する場合に用います。
  • たとえば、ログの書込処理を行うメソッドでのファイルへのアクセスや、システム内で共通のキャッシュテーブルを参照する場合などです。

アダプタ(Adapter)

  • アダプタとは現実世界の変換コネクタのようなものです。
  • 直接つながらないコネクタと差込口は、それらの間を変換コネクタが結び付けます。
  • コネクタと差込口にカスタマイズが不要な点がアダプタの利点です。
  • 関連性・互換性のないオブジェクトどうしを結び付ける必要があります

コンポジット(Composite)

  • 「全体〜部分」(個別のオブジェクトと合成したオブジェクト)を同一のものとしてとらえることで、再帰的な構造をクラスで表現する
  • 「全体〜部分」は同じインタフェースを継承します。
  • ファイルシステムなどの木構造を伴う再帰的なデータ構造を表現できる
  • 階層構造で表現されるオブジェクトの取扱いを楽にする
  • ディレクトリとフォルダを同様のコンポーネントとして扱うことで、削除処理などを再帰的に行えるようにできる

デコレータ(Decorator)

  • 既存のオブジェクトに対して簡単に機能の追加をするためのパターンです。
  • デコレータパターンを使うと、レイヤ状に機能を積み重ねて、必要な機能をもつオブジェクトを作ることができます。
  • 既存のオブジェクトの中身を変更することなく、機能を追加できる
  • 組み合わせでさまざまな機能を実現できる
  • 継承よりも変更の影響を限定しやすい

プロキシ(Proxy)

  • 1つのオブジェクトに複数の関心ことがある場合にそれを分離するために用います。
  • たとえば、オブジェクトの本質的な目的とは異なる「セキュリティ要件やトランザクション管理など」を切り離して実装できます。
  • プロキシには次の3つの種類があります。
    • 防御Proxy
    • 仮想Proxy
    • リモートProxy

コマンド(Command)

  • あるオブジェクトに対してコマンドを送ることでそのオブジェクトのメソッドを呼び出すことです。
  • たとえば、ファイルシステムの実装は知らなくてもユーザーはファイルの追加、削除といったコマンドを実行できます。
  • コマンドの変更・追加・削除に対して柔軟になる

インタプリタ(Interpreter)

  • ひとつひとつの問題はシンプルだが、組み合わさって複雑になるような場合に効果を発揮します。
  • 専用の言語を作り、その言語で得られた手順にもとづいて処理を実行していく

イーテレータ

  • 要素の集まったオブジェクト(配列など)にアクセスする
  • 集合の要素に順にアクセスする必要がある
  • 要素の集まりをもつオブジェクトの各要素に、順番にアクセスする方法を提供するためのデザインパターンです。

オブザーバ(Observer)

  • オブジェクトの状態が変化する可能性がある
  • 変化したことをほかのオブジェクトに通知する必要がある
  • 例としては、Aで起きたイベントをB, Cが知る必要がある場合などです。
  • オブジェクト間の依存度を下げることができる
  • 通知先の管理をオブザーバが行うことで、サブジェクトは通知側を意識しなくていい

ストラテジ(Strategy)

  • たとえば5ステップの中の3ステップが異なったAとBがあり、このAとBをスイッチしたい時に使えるパターンです。
  • 使用するアルゴリズムに多様性を持たせることができる
  • コンテキストと戦略を分離することでデータも分離できる
  • 継承よりもストラテジを切り替えるのが楽

テンプレートメソッド(Template Method)

  • 2つのコードのやりたいこと(アルゴリズム)がほとんど同じで、ある一部だけ変えたいようなパターンのときに有効です。
  • 抽象的なベースのクラス側に、「変わらない基本的なアルゴリズム」を置ける
  • 抽象的なベースのクラスは「高レベルの処理」を制御することに集中できる
  • サブクラス側に、「変化するロジック」を置ける
  • サブクラスは「詳細を埋めること」に集中できる
  • 「高レベルの処理」とは、プログラミング的には「抽象度の高い処理、ロジック的な部分、処理のフレーム」といった言葉に言い換えられると思います。
  • 「詳細を埋める」とは、プログラム的にはレポートの行を書き出すといった具体的な処理を指しています。

rails generateで生成されるもの

目次

概要

rails generateコマンドを使うと、Railsアプリケーションにおける基本的な機能の雛形を簡単に生成することができます。😊

しかし、コマンド実行時にどのようなファイルが生成されるのかを把握していないと、無駄なファイルが残ってしまい、ソースが煩雑になります。😢

そこで今回は、各種コマンドとそれに応じて生成されるファイルをまとめてみました!

検証環境

検証準備

Railsアプリケーションの生成

以下のコマンドでrailsアプリケーションを生成します。

rails new sample_app

Railsアプリケーションの起動

生成完了後、以下のコマンドでアプリケーションを起動します。

rails s

ブラウザでhttp://localhost:3000にアクセスし、以下のような画像が表示されたらOKです!

Git管理

各操作毎にコミットしておくと、コマンドで何が生成されたのか把握しやすくなるのでおすすめです!

(Gitの説明は割愛します🙏)

検証

rails generateの対象

rails generateの対象はなんと26個もあります。😳

(これらは、rails generate --helpで確認できます。)

今回はよく使われる4つ(⭐︎マーク)について検証します!

  • Rails:
    • application_record
    • assets
    • benchmark
    • channel
    • ⭐︎controller
    • generator
    • helper
    • integration_test
    • jbuilder
    • job
    • mailbox
    • mailer
    • ⭐︎migration
    • ⭐︎model
    • resource
    • ⭐︎scaffold
    • scaffold_controller
    • system_test
    • task
  • ActiveRecord:
    • active_record:application_record
  • RackProfiler:
    • rack_profiler:install
  • TestUnit:
    • test_unit:channel
    • test_unit:generator
    • test_unit:install
    • test_unit:mailbox
    • test_unit:plugin

rails generate model

rails generate model を使用することで、modelに関するファイルを生成することができます。

rails generate model {モデル名} {カラム名1}:{型名1} {カラム名2}:{型名2} ...

実際にコマンドを実行し、生成物を確認しましょう。

# 実行コマンド
rails generate model book title:string memo:text

# 実行ログ
Running via Spring preloader in process 82219
      invoke  active_record
      create    db/migrate/20221115151513_create_books.rb
      create    app/models/book.rb
      invoke    test_unit
      create      test/models/book_test.rb
      create      test/fixtures/books.yml

4つのファイルが生成されたことを確認できました。

modelやmigrateファイルだけでなく、テストファイルも作成されるのですね。 👀

rails generate migration

次は、既存のmodelに要素を追加・変更したい時に使用するrails generate migrationです。

操作内容によってrails generate migration以降の命名が変わるので注意です!🚨

# カラム追加の場合
rails g migration Add{カラム名}To{テーブル名} {カラム名}:{型名}

実際にコマンドを実行し、生成物を確認しましょう。

# 実行コマンド
rails generate migration AddAuthorToBooks author:string

# 実行ログ
Running via Spring preloader in process 82559
      invoke  active_record
      create    db/migrate/20221115152836_add_author_to_books.rb

migrateファイルが新たに生成されました。

操作内容がファイル名から読み取れるようになっており良いですね。👏

rails generate controller

続いて、controllerやview周りを生成するrails generate controller です。

rails generate controller {コントローラー名前(複数形)} {アクション名(省略可)}

実際にコマンドを実行し、生成物を確認しましょう。

アクション名あり

# 実行コマンド
rails generate controller books index

# 実行ログ              
Running via Spring preloader in process 82970
      create  app/controllers/books_controller.rb
       route  get 'books/index'
      invoke  erb
       exist    app/views/books
      create    app/views/books/index.html.erb
      invoke  test_unit
      create    test/controllers/books_controller_test.rb
      invoke  helper
      create    app/helpers/books_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    scss
      create      app/assets/stylesheets/books.scss

controllerやviewファイルの追加以外にも、routesへの追記も確認できます。

アクション名なし

rails generate controller books                        
Running via Spring preloader in process 82765
      create  app/controllers/books_controller.rb
      invoke  erb
      create    app/views/books
      invoke  test_unit
      create    test/controllers/books_controller_test.rb
      invoke  helper
      create    app/helpers/books_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    scss
      create      app/assets/stylesheets/books.scss

ファイル以外にもapp/views/booksディレクトリが作成されていました。

rails generate scaffold

最後に、アプリケーションの基本的な機能(一覧・詳細・新規作成・編集・削除)を実現するのに必要なファイルを一通り追加してくれるrails generate scaffoldを見てみましょう!

rails generate scaffold {モデル名} {カラム名1}:{型名1} {カラム名2}:{型名2} ...

実際にコマンドを実行し、生成物を確認しましょう。

# 実行コマンド
rails generate scaffold book title:string memo:text

# 実行ログ
Running via Spring preloader in process 83355
      invoke  active_record
      create    db/migrate/20221115160008_create_books.rb
      create    app/models/book.rb
      invoke    test_unit
      create      test/models/book_test.rb
      create      test/fixtures/books.yml
      invoke  resource_route
       route    resources :books
      invoke  scaffold_controller
      create    app/controllers/books_controller.rb
      invoke    erb
       exist      app/views/books
      create      app/views/books/index.html.erb
      create      app/views/books/edit.html.erb
      create      app/views/books/show.html.erb
      create      app/views/books/new.html.erb
      create      app/views/books/_form.html.erb
      invoke    resource_route
      invoke    test_unit
      create      test/controllers/books_controller_test.rb
      create      test/system/books_test.rb
      invoke    helper
      create      app/helpers/books_helper.rb
      invoke      test_unit
      invoke    jbuilder
      create      app/views/books/index.json.jbuilder
      create      app/views/books/show.json.jbuilder
      create      app/views/books/_book.json.jbuilder
      invoke  assets
      invoke    scss
      create      app/assets/stylesheets/books.scss
      invoke  scss
      create    app/assets/stylesheets/scaffolds.scss

基本的な機能を実現するべく、様々なファイルが生成されていることを確認できます。

小ネタ

コマンド省略

rails generategenerateは、gと省略することができます。

# 以下の2つは同じ
rails generate ~
rails g ~

generateコマンド取り消し

もしgenerateコマンドを間違えたを実行した場合は、rails destroy ~を使って生成されたファイルを削除することができます。

(rails g(generate) ~rails d(destroy) ~にするだけです。😳)

# 実行コマンド
rails d controller books

# 実行ログ
Running via Spring preloader in process 83700
      remove  app/controllers/books_controller.rb
      invoke  erb
      remove    app/views/books
      invoke  test_unit
      remove    test/controllers/books_controller_test.rb
      invoke  helper
      remove    app/helpers/books_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    scss
      remove      app/assets/stylesheets/books.scss

様々なオプション

rails generateは便利なコマンドですが、場合によっては不要なファイルも生成されます。

そんな時は、cofig/application.rbを編集して生成されるファイルを制御することができます。

おわり

いかがだったでしょうか?

適切な場面で適切なコマンドを使えるようになりたいですね!

ありがとうございました!😊👋

参考文献

VSCodeでのデバッグ操作解説(Ruby編)

目次

概要

デバッグにはいくつかの操作が用意されており、それらを適切に実行することで効率よく実装を進めることができます。

各操作で何ができるのかをまとめましたので、一緒に学んでいきましょう! 😊

アイコン紹介

VSCodeデバッグを実行すると、以下のようなアイコンが表示されます。

(デバッグ方法についてはこちらを参照)

これらは左から、

  • 続行
  • ステップオーバー
  • ステップイン
  • ステップアウト
  • 1つ戻る
    • 本記事では解説しません
  • 反転
    • 同上
  • 再起動
  • 停止・切断

となります。

サンプルコード

こちらのサンプルコードを使用して解説を進めます。

def main
    puts '処理を開始します。'

    first_method(5, 9)
    second_method(3)

    puts '処理を終了します。'
end

def first_method(x, y)
    puts '1つ目の関数です。'

    z = x + y
    puts "zの値は#{z}です。"

    z = double_method(z)
    puts "zの値は#{z}です。"
end

def double_method(x)
    x * 2
end

def second_method(x)
    puts '2つ目の関数です。'

    x.times do |count|
        puts "#{count}回目の処理です。"
    end
end

# main関数の実行
main

ブレークポイントについて

各種機能解説の前に、デバッグに必要不可欠な ブレークポイント を解説します。

ブレークポイントとは、確認したい処理につける目印のことです。 📌

目印をつけることで、その箇所で強制的に処理が一時停止され、実行内容を確認することができます。

また、ブレークポイントではどのような操作(再起動や中断を除く)を行ったとしても、処理が一時停止されます。

実際にデバッグ実行してみよう

ブレークポイントを設定しデバッグ実行すると、画像のように処理が一時停止されます。

また、一時停止時の変数の状態などを確認できます。

ブレークポイントを設定せずにデバッグ実行すると、一時停止することなく最後まで処理が進みます。

機能解説

(赤枠の箇所については解説を省きます。)

続行

次のブレークポイントまで処理を進めます。

次のブレークポイントがない場合は、最後まで処理が実行されます。

before

この状態で続行すると、次のブレークポイントである26行目まで一気に進みます。

after

ステップイン

1行づつ処理を進めます。

関数があった場合、その関数の内部の1行目に移行します。

関数がない場合

before

after

変数zの値が14に更新されています。

関数がある場合

before

after

double_methodの1行目に移動していることがわかります。👀

ステップオーバー

1行ずつ処理を進めます。

関数があった場合、その関数を実行して次の行に移行します。

ステップインと間違えやすいので注意です!🚨

関数がない場合

before

after

関数がある場合

before

after

double_methodが実行され、変数zの値が28に更新されています。

ステップアウト

実行している関数の外(呼び出し元)に出るまで処理を進めます。

before

after

first_methodの最終行まで処理が進んでいることがわかります。

また、double_methodが実行され、変数zの値が28に更新されています。

再起動

デバッグ実行を終了し、再度実行します。

停止・切断

デバッグ実行を中断します。

おわり

いかがだったでしょうか?

ステップ系の各操作については、

  • 関数に入る → ステップイン
  • 関数をまたぐ → ステップオーバー
  • 関数から出る → ステップアウト

とすると覚えやすいかもです!

サンプルコードでは様々な状況で実行できるようになっているので、ぜひご活用ください!💪

nodebrewでnodeがインストールできない時の対処法

目次

使用環境

nodebrew installできない

nodebrew install {バージョン名}で node をインストールしようとしたが、以下のようなエラーが発生した。

$ nodebrew install v15.14.0
v15.14.0 is not found

Can not fetch: https://nodejs.org/dist/v15.14.0/node-v15.14.0-darwin-arm64.tar.gz

解決策

以下のコマンドでインストールが成功した。

(ただし、かなりの時間がかかるので注意。1時間30分ほどかかった記憶。。)

# nodebrewのホームディレクトリ($HOME/.nodebrew)配下にsrcディレクトリが存在しない場合は作成する
$ cd ~/.nodebrew
$ mkdir src

$ nodebrew compile v15.14.0

参考記事

VSCodeでRailsをデバックしたい!

目次

使用環境

  • MacBook Pro(14インチ、2021)
  • macOS Monterey(バージョン12.5)
  • ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [arm64-darwin21]
  • Rails 6.1.6

VSCodeRailsをデバックする2つの方法

VSCodeRailsデバッグする方法は、ざっと調べたところ2点ありました。

  • ruby-debug-ide の使用
    • バージョン違いによりアウツ...
  • debug.gem の使用
    • こちらで実行できました! 👏

ruby-debug-ide の使用

以下の記事を参考にしてインストールを進めていたのですが、gem install debaseでエラーが発生しました。

zenn.dev

原因はRubyのバージョンによるものでした。

訳あって3.1.1を使用したく、別の方法であるdebug.gemを使用することにしました。

debug.gem の使用

以下の記事を参考に、以下のような流れで環境構築を進めました。

  1. debug.gemのインストール
  2. Rudyでデバッグできることを確認
  3. VSCode拡張機能をインストール
  4. VSCodeからRudyのデバッグができることを確認
  5. VSCodeからRailsデバッグができることを確認

zenn.dev

流れをみると、「最初からRailsで確認すればいいじゃん!」と思いますよね?

最初は同じ考えでRailsの確認から進めていました。

しかし、エラーが連発し原因が特定できず、結局かなりの時間をかけてしまいました。。

問題を正確に切り分けるためにも、着実に進めることをおすすめします。

実行できるまでに試したこと

記事を参考にしても動かない場合は、以下を確認すると解決するかもしれません!

  • Gemfileを編集した後、bundle installを実行する
  • launch.jsonの内容に差異がないことを確認する
  • Debug command lineでbundle exec ruby bin/rails serverを実行する
  • VSCodeを再起動する
  • 流れを確認し、問題を切り分ける

おわり

ばしばしデバッグ使っていきます!!!