Code Journey

30代未経験からプログラミング挑戦中(追うものは追われる者に勝る)

【2024.4.6更新】これまで学習してきたこと&学習時間

私は現在、フィヨルドブートキャンプで、未経験からプログラミング学習をしているものになります。

これまで何をどれくらい学習したかを一覧で確認できるように記述していくページになります。 以下2点を目的としています。

  • 自分のモチベーションの維持のため
  • 就職活動の際にざっくり何を取り組んだかを確認できるようにする

学習時間

合計学習時間:1478.8時間 (2024/4/6時点)

これまで学習してクリアしたプラクティス

学習の準備
学習の進め方を知る
チャットを使えるようになる
ブログを作る
SNSの登録
GitHubアカウントの登録
日報を書く
質問をする力をつける
開発環境
開発環境を作る
HTML & CSS
HTMLの基本を理解する
Markdown を使って HTML を書く
CSS初級
Vi
vi の基本を理解する
Linux
Terminalの基本を知る
Linux をインストールする
UNIXLinux について知る
Linux のファイル操作の基本を理解する
apt の基本を理解する
sudo をインストールする
SSH の基本を理解する
標準入出力・リダイレクション・パイプを理解する
SSL/TLS の基本を理解する
Git & GitHub
Git の基本を理解する
GitHub の基本を理解する
Pull Request を行う
Ruby
rbenv
Ruby初級
FizzBuzz問題(Ruby)
カレンダーのプログラム(Ruby)
rubygems の基本を理解する
プログラムの修正
Bundler の基本を理解する
rubocop の使い方を知る
ボウリングのスコア計算プログラム
Ruby中級
プログラムの修正(リバーシ編)
lsコマンドを作る1
lsコマンドを作る2
lsコマンドを作る3
lsコマンドを作る4
ls コマンドを作る5
wc コマンドを作る
HTTP
HTTP の基本について理解する
Cookie について理解する
Nginx
nginx の基本を理解する
nginx で VirtualHost を使って 1 つのサーバーで複数のサイトを立ち上げる
nginx で SSL 対応サイトを作る
データベース
SQL の基本を理解する
PostgreSQLの基本を理解する
データベース設計の基本を理解する
Webアプリケーション
REST の考え方を理解する
Sinatra を使ってWebアプリケーションの基本を理解する
WebアプリからのDB利用
Ruby on Rails
Rails の基本を理解する
Railsi18n を理解する
kaminari を使ってページング処理を実装する
devise を使ってユーザー認証を実装する
ActiveStorage で画像アップロードを実装する
コメントを付けられるようにする
日報の言及機能を実装する
オープンソースソフトウェア開発
OSS にコントリビュートする方法を知る (Issueを立てる)
OSS のソフトウェアプロジェクトに PR を送る
自動テスト
テスト技法
TDD の基本を理解する
test-unit の基本を理解する
Railsでテストを書く
オブジェクト指向プログラミング(Ruby)
オブジェクト指向プログラミング
ボウリングのスコア計算プログラム(オブジェクト指向版)
lsコマンド自作(オブジェクト指向版)
JavaScript
JavaScript入門
JavaScript環境の設定
npm
Linter (ESLint) と Formatter (Prettier)
FizzBuzz問題(JavaScript)
カレンダーのプログラム(JavaScript)
非同期処理(JavaScript)
npm パッケージの作成
React
Reactチュートリアル
Reactを学ぶ
ReactでSPAを作る
Contextを使ってグローバルなstateを管理する
SWRを使ってAPIをコールする
Webセキュリティ
アジャイル開発 /スクラム を理解する
チーム開発
アジャイル開発 /スクラム を理解する
ビデオチャットを使えるようになる
開発に参加するための準備をする
開発に参加して PR を送りマージする

今後取り組む課題

Webサービスを作って公開する

RailsのAPIモードとは?基本的な使い方について調べてみた

はじめに

前提

まず前提として、この記事を書いているのは未経験からプログラミングに挑戦中の者になります。学習はフィヨルドブートキャンプ(以下 FBC)に参加しながら取り組んでいて、現役のエンジニアの方からレビューをもらいながら進めています。

現在の学習状況は以下を随時更新しているので興味ある方はご覧ください。

hirano-vm4.hatenablog.com

フィヨルドブートキャンプは終盤にアジャイル/スクラムでのチーム開発のプラクティスに取り組みます。しかも、これまで自らが使ってきたFBCアプリを開発します。

このFBCアプリはAPIが使われています。

今回はチーム開発に入るにあたって、RailsAPIモードについてよく知らなかったことをきかけにインプットしました。せっかくのなので、調べたことをまとめてアウトプットしておきたいと思います。

というのも、これまでのプラクティスでRailsをやってきましたが、APIモードが扱ってきませんでした。

しかし、チーム開発で取り組むフィヨルドブートキャンプアプリはAPIモードを使ってフロントとやりとりしている部分があるようなので、概要だけでも理解しておかないと!と思い題材にしました。

現場レベルで使用した意見ではなく、あくまで利用前に調べたことをまとめた記事になりますので、その点はご注意ください。

ということで、ここからが本題になります。

Ruby on RailsAPIモードとは

Rails におけるAPIモードは、「React.js や Vue.js のような他フロントエンド技術との連携を目的として、MVCアーキテクチャーのフロントエンド領域に相当する V(View) を捨てて、 JSON API としてのみ振る舞うバックエンド領域特化のアプリとして開発するモード」のことです。

後述しますが、完全にViewを捨ててJson APIに専念するだけでなく、Viewをこれまで使いながら一部分をAPIモードとして活用するハイブリットな形式でも用いることも当然できるようです。

なぜAPIモードが存在するのか

  • RailsMVCアーキテクチャーによって、フルスタックにアプリ開発を行えるフレームワークであるが、Reactなどフロントエンド技術の進歩により、SPA(Single Page Application)が注目されてきた

  • React.js や Vue.js のようなモダンなフロントエンド技術は、「フロントエンドに特化したアプリケーションを構築する技術であり、バックエンドは別に用意する」ことを前提としている

  • それによってRailsはバックエンドに特化する使い方もするようになってきた

このような理由からAPIモードが登場し、使われるようになってきたようだ。

JSON APIRailsを使う理由

ではなぜ、JSON APIRailsを使うのか。RailsガイドのRails による API 専用アプリケーションに説明が書いてありました。

例えば「RailsJSONを出力するのは大げさでは?」、「もっと軽量なフレームワーク(例えばSinatra)でも同じことができるのでは?と疑問に思うかもしれないが以下のようなメリットがRailsを使うことで享受できるとのことです。

  1. 開発の迅速化: Railsは「設定より規約」の哲学に基づいており、多くのデフォルト設定がすでに最適化されているため、開発者は細かい設定に時間を費やすことなく、すぐにアプリケーションの開発を開始できる。

  2. 豊富な機能: Railsは、開発の各段階で役立つ多くの機能を提供する。これにはミドルウェア層での透過的な再読み込み、開発環境での便利なデフォルト値、テストとログ出力のサポート、セキュリティ対策、パラメータ解析、条件付きGETの処理、HEADリクエストのサポートなどが含まれる。

  3. セキュリティ: RailsはIPスプーフィング攻撃やタイミング攻撃などのセキュリティ脅威を検出し、防御する機能を備えている。これにより、アプリケーションの安全性が高まる。

  4. RESTful APIのサポート: Railsはリソースベースのルーティングをサポートしており、RESTful APIの開発が容易になる。これにより、HTTPの規則に従った明確なURL構造でAPIを構築可能。

  5. 便利なツールとプラグイン: Railsには、開発を加速させるための多数のジェネレータ、プラグイン、ライブラリがあります。これらを利用することで、開発者はより高度な機能を簡単に追加でき、開発プロセスをスムーズに進めることができる。

  6. 統合環境: Railsはモデル、ビュー、コントローラ(MVC)のフレームワークを採用しており、APIのバックエンドロジック、データベースの操作、フロントエンドとの通信など、アプリケーション開発の全ての側面を統合的に扱うことができる。

要するに、Railsを使用すると、開発者は迅速にアプリケーションを立ち上げることができ、セキュリティ、パフォーマンス、開発の利便性など、多くの面でメリットを享受できるということです。

ビュー層を除外しても、「ほとんどの機能」を引き続き利用できるため、API開発にも非常に適してるというのが理由のようです。

API専用Railsアプリケーションを新規で作成する場合

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

API専用Railsアプリケーションを作るには以下のコマンドを使う

$ rails new my_api --api

このコマンドによって以下の設定がされます。

  1. ミドルウェアの絞り込み:

    • Railsアプリケーションは、リクエストの処理にさまざまなミドルウェアを使用する。APIモードでは、ブラウザからのアクセスに必要なミドルウェア(例えば、クッキーのサポート)を除外し、APIサーバーとしての機能に特化させたミドルウェアスタックを使用する。
  2. ApplicationControllerの変更:

    • 標準のActionController::Baseではなく、ActionController::APIを継承したApplicationControllerが生成される。これにより、ビューをレンダリングするための機能など、APIサーバーには不要な機能が除外される。
  3. ビュー、ヘルパー、アセットの生成の無効化:

    • API専用アプリケーションでは、HTMLビュー、ビューヘルパー、アセットファイル(CSSJavaScript)は必要なくなる。そのため、これらのファイルを生成するジェネレーターがデフォルトで無効に設定される。

新しいリソースの作成

例としてグループのデータを管理するためのGroupというリソースを作成する。 Railsでは$ bin/rails g scaffoldコマンドを使って、リソースに関するモデル・ビュー・コントローラー・マイグレーションファイルを一度に生成できる。

$ bin/rails g scaffold Group name:string

このコマンドは、Groupという名前のモデルと、それに紐づくname(型はstring)を「持つテーブルを作成します。

データベースのマイグレーション

生成したマイグレーションファイルを使ってデータベーススキーマを更新する。これにより、groupsテーブルがデータベースに作られます。

$ bin/rails db:migrate

コントローラーの確認と修正

scaffoldコマンドで生成されたGroupsControllerはデフォルトでJSON形式でデータを返すように設定されています。

API専用Railsアプリケーションの生成した場合ですのでご注意ください

$ rails new my_api --api

これにより、APIとして機能します。例えばindex アクションでは全てのグループを取得してJSON形式で返します。

そのほか、show、create、update、destroyアクションでは、それぞれ特定のグループの詳細を表示、新しいグループを作成、グループの情報を更新、グループを削除する処理を行います。

データを確認する

サーバーを起動して、ブラウザからhttp://localhost:3000/groups.json:titleにアクセスすると、データをJSON形式で確認することができます。

既存のRailsアプリケーションをAPI専用アプリケーションに変更する方法

ここからは、既存のRailsアプリをAPIモードに変更する方法になります。

APIモードの設定

まず、アプリケションをAPI専用モードに変更します。

config/application.rbファイルを開き、Applicationクラスの定義の冒頭に以下を追加します。

module YourApp
  class Application < Rails::Application
    config.api_only = true
  end
end

これにより、アプリケーションがAPIモードで動作するようになる。

開発モードでのエラー表示の設定

開発中にエラーが発生した時のレスポンス形式を設定する。これにより、エラーが発生した際にどのような情報を表示するのかを制御できる。

  • HTML形式でのエラー表示 config/environments/development.rbファイルにconfig.debug_exception_response_format = :defaultを設定すると、エラーが発生した際にHTMLページでデバッグ情報が表示される。これは、従来のWebアプリケーション開発時に親しみやすい形式。

  • API形式でのエラー表示 同じファイルにconfig.debug_exception_response_format = :apiを設定すると、エラーが発生した際にAPI形式(通常はJSON)でデバッグ情報が返さる。これは、API専用アプリケーションを開発している場合に適している。

APIモードであれば、config.debug_exception_response_formatデフォルトで:apiに設定されている。

ApplicationControllerの継承先の変更

アプリケーション全体でAPI関連の機能を使用するために、ApplicationControllerの継承元をActionCntroller::BaseからActionController::APIに変更する。

これによりビューをレンタリングするためのメソッドなどAPIに不要な機能が削除される。

変更前

class ApplicationController < ActionController::Base
end

変更後

class ApplicationController < ActionController::API
end

この変更を行うことでアプリケーションはAPI専用モードで動作するようになり、バックエンドからフロントエンドにデータを送信する際にJSONなどの形式を利用するようになる。

これにより、フロントエンドとバックエンドを分離したモダンなWebアプリケーションの開発が容易になるとのこと。

RailsAPIモードと通常のモードを混在する方法

API専用のコントローラーの作成

API 機能を提供する部分については、ActionController::APIを継承したコントローラーで作成する。これにより、APIに必要な昨日のみを持った継承なコントローラーが作成できる。

class Api::V1::ExampleController < ActionController::API
  def index
    # API用のアクションをここに記述
  end
end

通常のコントローラー

従来のRailsアプリケーションとしてビューを提供する部分には、これまでのように通常通りActionController::Baseを継承したコントローラを使用する

class PagesController < ActionController::Base
  def show
    # ビューを提供するアクションをここに記述
  end
end

ルーティングの設定

APIとビューを提供する部分のルーティングを適切に設定する。

API用のルーティングは、通常namespaceを使ってグループ化し、URLに/api/v1/などを含めることが一般的。

Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      resources :examples, only: [:index]
    end
  end

  get 'pages/show'
end

フロントエンドとの統合

ReactなどのフロントエンドフレームワークRailsと統合して利用する。

WebpackerやRails 7以降で導入されたjsbundling-railsなどのツールを使用して、フロントエンドのビルドシステムをRailsと組み合わせることができる。

さいごに

以上、RailsAPIモードについて予習まとめでした。

今後、実践していく中で追記したほうがよさそうなことがあれば、リライトしていきたいと思います。

チーム開発が終わったらいよいよ自作サービスの作成に入るので気合をいれて学習に取り組んでいきたいと思います💪

参考にしたサイト

Rails による API 専用アプリケーション - Railsガイド

「Rails API とは?普通の Rails と何が違うの?」と思った人がまず読む記事

アジャイル開発 / スクラムについて学習したことまとめ

はじめに

前提

まず前提として、この記事を書いているのは未経験からプログラミングに挑戦中の者になります。学習はフィヨルドブートキャンプ(以下 FBC)に参加しながら取り組んでいて、現役のエンジニアの方からレビューをもらいながら進めています。

現在の学習状況は以下を随時更新しているので興味ある方はご覧ください。

hirano-vm4.hatenablog.com

今回は、チーム開発のプラクティスに入るにあたって「アジャイル開発/スクラム」について学習し、その内容をアウトプットしたいと思います。

注意点としてスクラムを実践したわけでなく、これから実践するにあたって書籍などで学んだこと、それを受けて個人的に感じた所感について書いた記事になりますのでお気をつけください。

アジャイル開発について

アジャイル開発とは

アジャイル開発とは、システム開発の手法のひとつで、短いサイクルで開発とリリースを繰り返す開発手法のことを指します。

一度開発をしてリリースしたら終わりではなく、アジャイル開発ではリリースし、ユーザーからフィードバックを受け、それを優先順位に反映させて改善するというサイクルを短い期間で繰り返していく開発手法です。

また開発する単位にも特徴があります。アジャイル開発では、作成するシステムの単位を小規模な機能ごとに分割して、それぞれを企画からリリースまでを繰り返していきます。

各機能改善・追加のリリースごとに、 スプリント のサイクルを繰り返していきます。

イテレーションは、「計画」「設計」「実装」「テスト」の工程を反復することを指します。各機能の実装はこのサイクルを繰り返していきます。

私たちが現在使っているフィヨルドブートキャンプのWebアプリもアジャイルで開発されていて、毎週新しい機能がリリースされていることが確認できます。

また、私自身も普段利用しているアプリを使う際は、バグの改善・新しい機能の追加など日々機能が追加・改善される前提でサービスを利用していることに、この課題でアジャイルについて学んだことで気付かされました。

使っているアプリなどのアップデートの情報をみても、頻繁に更新されていることがわかります。

スクリーンショット 2024-02-25 20.53.42.png

Google Chromeのアップデート履歴を確認してみた


このようにユーザーの意見などを取り入れてスピード感のある開発をしたい場合には、このアジャイル開発が向いています。

なぜアジャイル開発が必要なのか

インターネットが普及する前のソフトウェア開発では、リリースすることがゴールとなってましたが、近年はインターネットやスマートフォンなどの通信端末の普及などもあって、リリース後のアップデートが可能になりました。

そのようなビジネス環境の変化もあって、現代は売り切って終わりでなく、サブスクリプション型へのビジネスモデルの変化がみられました。

このサブスクリプション型への変化は、ユーザーが気軽にサービスを利用できるようになった反面、逆にユーザーの求めるUXでない場合、すぐにサービスから離脱することに繋がります。

それを防ぐために、継続的に機能追加や改善をして、ユーザーに長くサービスを利用継続してもらうことが重要視されるようになりました。

「継続的な改善が前提」となっているアジャイル開発は、リリースしてからフィードバックを受けて、必要あれば優先順位を変更するなど、ユーザーのニーズを反映させやすい開発手法で注目されています。

アジャイル開発の価値観

アジャイル開発は、2001年にアメリカのソフトウェアエンジニアであるケント・ベックらがまとめた「アジャイルソフトウェア宣言」で示されています。

スクリーンショット 2024-02-25 20.57.20.png


  • プロセスやツールよりも個人と対話を、
  • 包括的なドキュメントよりも動くソフトウェアを、
  • 契約交渉よりも顧客との協調を、
  • 計画に従うことよりも変化への対応


このように左の青字のものにも価値があるとしつつも、アジャイル開発では右の赤字の 「個人との対話」「(ドキュメントよりも)動くソフトウェア」「顧客との協調」「変化への対応」 を大切にすると宣言されています。

この宣言から、まず小さくリリースして、動くものを見てからフィードバックをもらい、優先順位を設定して、プロダクトを改善していくという価値観であることが読み取れます。

留意しておかなければならないのは、赤字の概念が不要だと考えて「ドキュメントを作らない」「計画をせずに手を動かす」という意味ではないことです。

たとえ、アジャイル開発であっても計画やドキュメントも必要になる場面は存在します。

あくまで判断基準はアジャイル開発で重視する 「個人との対話」「(ドキュメントよりも)動くソフトウェア」「顧客との協調」「変化への対応」 であるが、それを実現するために、必要になるドキュメントや計画であれば、当然取り入れるべき というスタンスであるという理解を私はしました。

アジャイル開発はプロダクトだけでなく現場も変化する

アジャイル開発は、変化することを前提にしています。それは、プロダクトだけでなく 開発の進め方の変化も対象 としています。

開発してく中で、開発過程で課題があった場合プロセス自体も変化させていきます。

【例】
  • メンバー同士の状況が把握できていないのであればタスクボードを取り入れる。
  • コードレビューで戻りが多い課題があった場合、モブプログラミングを取り入れて齟齬を減らす


このように、一貫して同じことをするのでなく、開発過程で必要であれば、開発現場も変化していきます。

もちろん、一定の効果が得られたのでモブプロを一時中止するという判断も含まれます。

アジャイル開発では、開発の効率を高めるためにその都度、状況を把握して、その時々にあった形に開発方法も、プロダクトの機能追加の優先順位も変化していきます。

アジャイル開発のメリット

顧客が本当に欲しかったものにアプローチできる

ソフトウェア開発において「開発したけど使われない」「思っていたものと違った」となってしまう問題が往々として存在する。

ある調査によると完成した機能の60%は使われていないという結果も公表されています。

これがなぜ起こるのかというと、「利用者の課題を解決するもの」とずれてしまっていることが原因です。

「開発する側が考える需要」と、「利用者側が考える需要」は一致するとは限りません。

これはソフトウェア開発だけでなく、他の仕事であっても同様です。「クライアントの意見を聞かずに、自分だけの考えで資料を作って、クライアントに提案してみたら全く需要がなかった」なんて失敗はよくあるかと思います。

また、リリースされたものを見て意見が変化したり、時間とともに需要も変化することもあります。

アジャイル開発では、先述したように リリースし、ユーザーからフィードバックを受け、それを優先順位に反映させて改善するというサイクルを短い期間で繰り返していく開発手法 です。

そのためアジャイル開発は、 仕様変更・追加機能・優先順位の変化にも対応しやすい開発手法 だといえます。

また開発する側も、その都度コミュニケーションをとって意見交換をしながら開発ができるので、困りごとを共有しやすい環境になることもメリットになりそうだと個人的にも感じました。

スクラム

スクラムとは

スクラムは、アジャイル開発の手法の1つで、少人数のチームに分かれて短期間の開発サイクルをくり返し行うフレームワークのことを指します。

スクラムには以下のような特徴があります。

  • ニーズを「価値」「リスク」「必要性」などを基準にして優先順位をつけて並び替えて、その順番で開発を進めることで成果を最大化する

  • スクラムでは固定の短い時間に区切って作業を進める(タイムボックス

  • その時点での、現状や問題点を明らかにする(透明性

  • 定期的に進捗状況・期待されている成果が得られているか・進め方に問題はないかを確認する(検査

  • 問題があればやり方そのものも変化させる(適応


このような特徴から、スクラムわからないことが多い複雑な問題を扱うプロダクトに適した開発手法 といえます。

スクラムは, 5つのイベント(会議)構成・3つのロール(役割)・3つの制作物 などの最低限のルールで構成されています。

スクラムのサイクル

スプリントバックログ


上記の画像にスクラムで必要とされる5つのイベントと3つの作成物の関係を可視化しました。

完成に向けて目標を細かな単位に設定し、それを毎回のサイクルに落とし込み、そのサイクル内で開発をしてレビューをして、フィードバックを次のサイクルに反映させて、を繰り返していきます。

小さい単位で開発と改善を繰り返すので、問題・課題が発生すれば開発体制を変更したり 、優先順位も入れ替わったりと柔軟に対応していきます。

これはよく言われるPDCAサイクルを回していくようなイメージだと私は捉えました。

スプリント

スクラムでは、通常1から4週間までの固定の期間で区切り、そのサイクルで開発を繰り返します。この期間のことを スプリント といいます。

スクラム開発におけるスプリントは、プロジェクトの進行を促進するための基本的な単位で、 この期間中にチームはプロダクトバックログから選ばれたアイテムを完了させる ことを目指します。

スプリントは、製品の迅速なリリースと、継続的な改善を可能にします。短い反復周期を通して、チームは製品の品質を維持しながら、顧客からのフィードバックを素早く取り入れることができます。

スプリントはチームに焦点とリズムをもたらし、透明性とコミュニケーションを促進します。

スプリントのような短いサイクルで、話し合う場面が設定されて区切りもあるので、開発する側にとっても悩みや困りごとを相談しやすい環境ですね。

プロダクトバックログ

まず、プリントを回していくにしても何をどの優先順位で取り掛かるかを定めなければ始まりません。

スクラムでは、 機能・要求・要望・修正などプロダクトに必要なものを抽出し順番に並べ替えたプロダクトバックログを作成 します。これは、1プロダクトにつき1つ作成されます。

プロダクトログのリストの順番は、その項目の価値やリスク、必要性などによって決定されます。上位にある項目がより重要度が高いものになります。

また、それぞれの項目は見積もられている必要があります。この 見積もりには時間や金額などの絶対値ではなく、作業量を相対的に表した値が用いられます。

このプロダクトバックログは一度完成したら終わりではなく、常に変化する要求や状況を反映して更新していく必要があります。それに伴って項目の順序も変化します。

スプリントを回し、スプリント終わりにフィードバックを反映させて、優先順位などの更新して次のスプリントに入ります。すべての始まりはプロダクトバックログから始まります。

そのためプロダクトログは 常に更新し続け、最新に保たなけばいけないもの です。

このプロダクトバックログから始まり、フィードバックもこのプロダクトバックログに返ってくると考えると、このスクラムにおいて非常に重要な役割を果たすことが、これまでの説明からも伺えます。

スプリントバックログ(スプリント計画)

プロダクトバックログの次は、 スプリントプランニング(スプリント計画) です。

スプリントを始めるにあったって、今回のスプリントで何をどれくらいまで作るのかを落とし込みます。

スプリント計画に使える時間は1ヶ月のスプリントの場合は8時間。スプリントの期間はそれよりも短い場合は、それに合わせて短くするのが通常です。

スプリントバックログで2つのトピックを扱う

1つ目は、 スプリントで何を達成するのかを決める ことです。
  1. 最初にプロダクトオーナー(後述)が今回のスプリントで達成したい目的を明らかにする
  2. 今回のスプリントでそれを達成するために完成させるプロダクトバックログ項目を選択
    ※選択する項目はプロダクトバックログの上位のものになるのが通常。また、選択する個数は各項目の見積もりサイズや開発の過去の実績(ベロシティ)、スプリントで使える時間を踏まえて仮決定
  3. 検討した内容を踏まえて今回のスプリントの目標を簡潔にまとめる(スプリントゴール)
    開発チームがなぜここで選択したプロダクトバックログ項目を開発するのか理解しやすくなる。


このように、プロダクトバックログの上位から順に、今回のスプリントで開発する対象を選択するため、事前にプロダクトバックログの上位の項目については準備が必要です。

プロダクトバックログリファインメイト

プロダクトバックログの上位の項目の準備のことを「プロダクトバックログリファインメント」と言います。

  • 項目の中身を具体的にする
  • 項目の疑問を解決する
  • 項目は何ができたら解決なのか(受け入れ基準)
  • 項目を自分たちが扱えるサイズに分割する
  • 項目を相対的に見積もる etc


やはり、プロダクトバックログの説明の最後に書いたように、プロダクトバックログが最初の起点であり、重要であることがこの説明からもわかりますね。

②開発チームがどうやって選択したプロダクトバックログ項目を実現するか

2つ目は、「開発チームがどうやって選択したプロダクトバックログ項目を実現するか」について計画を立てます。

選択した項目ごとに具体的な作業を洗い出すなどをして作業計画を立てます。

スプリントバックログ

選択したプロダクトバックログ項目と作業の一覧を合わせて スプリントバックログ と言います。

スプリントバックログ開発チームの開発計画であり、スプリント期間中も自由に作業を追加したり削除することができるものです。

ちなみに、ここの作業については1日以内で終わるように分割するのが一般的な方法です。難しい状況があればプロダクトオーナーと相談し、項目を調整したり、計画を見直すなどの調整を行います。


注意しなければいけないのは、開発チームはスプリントプランニングで決定した方針を完遂するよう全力を尽くす必要はあるが、計画したことを全て完成させることを約束しているわけではない、ということです。

すべての完成を約束してしまうと、見積もりが外れる、難易度が高かったり、不測の事態が起こったりした際に、開発チームが長時間残業になってしまったり、必要な作業を省くなどの問題につながる可能性がある。

この部分については、近年、納期とノルマを遵守を求めるあまりに商品の品質に問題が発生したり、不正につながる事件が起きていることを考えると想像がしやすいと感じました。

もちろん守れる技術力を磨くことは重要ですが、難しい時に相談しやすい雰囲気や関係性、柔軟な方向修正も長い目線でめると重要だと感じますね。

デイリースクラム

デイリースクラムはスプリントの中で、毎日行われる短いミーティングのことを指します。チームメンバーが何に取り組んでいるか、何か問題はないかを共有し、ゴールの達成に向けて進んでいるか毎日検査します。

デイリースクラムは、開発チームの人数に関係なく15分間のタイムボックスで行い、延長はしません。

デイリースクラムはの進め方は特に決まりはないが以下の点について確認することが多い。

  1. スプリントゴール達成のために、自分が機能やったことは?
  2. スプリントゴールを達成するために、自分が今日やることは?
  3. スプリントゴールを達成する上で、障害になることはあるか?


このようなことを共有して、スプリントがゴールに近づいているかを確認します。確認するだけでなく場合によっては、メンバー間で協力したり、方法を変えるなどの修正をしていきます。

注意しなければいけないのは、デイリースクラム自体は問題解決の場面ではないということです。問題を把握し、対処が必要な場合は、デイリースクラム終了後に時間を作って、必要な人で別途相談の場を設定します。

あくまで15分というタイムボックスは守ります。これは現在地を確認し、問題があれば把握するという役割がデイリースクラムにはあるということだと思います。

インクリメント

ここからスプリントの終わりに向かっての流れの話になっていきます。 スクラムでは、スプリント単位で評価可能なインクリメントを作ることが求められます。

インクリメントとは、過去に作ったものと、今回のスプリントで完成したプロダクトバックログ項目を合わせたものです。

多くの場合は、動作するものとして提供され、スプリント終了時点で完成していて、正常に動かなかればいけません。

そのため、プロダクトオーナーと開発チームが「完成」と考える基準を共有していなかればいけません。この基準のことを「完成の定義」と呼びます。

開発チームはこの基準の定義を満たすプロダクトを開発しなければなりません。

この完成の定義を擦り合わせておかないと、双方の基準がズレるということがよくあるのはどの業界の仕事にこいても重要なことなのでイメージしやすいかと思います。

ちなみに、この完成の定義は「品質基準」とも言い換えることができます。

スプリントレビュー

スプリントレビューは、プロダクトオーナー主催でスプリントの終わりに行われるミーティングです。スプリントで完成した製品のデモを行い、ステークホルダーからのフィードバックを受け取ります。

この フィードバックが最大の目的 です。

スプリントレビューでは、開発チームがスプリント中に完成させたインクリメントを実際にデモします。これは、プレゼンテーションによる説明ではなく、実際に動作する環境を見せながら確認 できるようにします。

動かしながら説明し、場合によって実際に触ってもらってフィードバックを引き出します。

実際に動作する環境を見せながらの確認は、実際に画面を見て、動かしてもらうことで開発チームとステークホルダーなどの方向性のずれの修正や、間違っていないことが確認できる重要な場面だと感じますね。

スクラムのように短い期間でそのような機会があるということが大きなずれになる前に修正もしやすくなり、スクラム開発の大きなメリットの一つであることが学習していても想像できた部分でした。

ちなみに、このスプリントレビューでデモすることができるのは当然、完成したものだけです。

そのためスプリントレビューの前までに完成したプロダクトバックログと、そうでないものを整理しておくのが一般的と言われています。

また、その上でデモを行い以下の点についてスプリントレビューで報告・議論します。

  • スプリントで完成しなかった項目を説明
  • うまくいかなかったことやその問題点、解決した方法について議論する
  • プロダクトオーナーがプロダクトの状況やビジネス環境について説明する
  • プロダクトバックログに追加するべき項目がないかを確認する
  • 今後開発していく上で問題となる点を確認する
  • 現状の進捗を踏まえてリリース日や完了日を予測


この議論で得た内容は、必要に応じてプロダクトバックログに反映します。

ここで得た内容がプロダクトバックログに反映されるので起点はやはりプロダクトバックログです。毎回のスプリントの内容が反映されて、最新の状態をもとに次のスプリントに入っていくことになり、良い循環が生まれるのだと思います。

ちなみに、スプリントレビューに使える時間は、1ヶ月スプリントであれば4時間、スプリントがそれよりも短い場合はそれに応じて短くするのが一般的と言われています。

スプリントレトロスペクティブ

スプリントレトロスペクティブは、スプリントの終わりに行われる最後のミーティングで、チームがスプリントの過程を振り返り、改善点を議論します。

  • まっとうまく仕事を進める方法はないか検討し、改善を繰り返す
  • バグの修正では、バグが発生する原因を探る
  • 人、関係、プロセス、ツールなどの観点で今回のスプリントを検査する
  • 今回うまくいったこと、今後の改善点を整理
  • 今後のアクションプランをつくる
  • 一度にたくさんのことを変更しようとしない


このように毎回の短いスプリントの期間で良い部分と改善点を認識し、修正していくことができるのはスクラムのメリットだと感じます。悪い部分だけでなく、良い部分を認識するという点についても個人的には魅力に感じました。

ちなみにこのスプリントレトロスペクティブに使える時間は、1ヶ月のスプリントの場合で3時間程度で調整します。

スクラムの登場人物

この項目ではスクラム開発に登場する登場人物をそれぞれ解説します。

プロダクトオーナー

プロダクト製品のビジョンを持ち、プロダクトバックログを管理する役割を担う責任者をプロダクトオーナー(PO)と呼びます。1つのプロダクトにつき1人設定し、プロダクトバックログの項目の並び順の最終決定権を持ちます。

プロダクトのWhatを担当し、ステークホルダーとチームの間でコミュニケーションを取り、製品の価値を最大化します。プロダクトバックログが完成しているか確認も行います。

しかし、プロダクトオーナーは開発チームに相談はできますが干渉はできません。

製品の価値を最大化する責任があるのためプロダクトバックログの項目の並び順を決定する以外に以下のような仕事も行います

  • プロダクトのビジョンを明確に持ち、周囲と共有
  • おおよそのリリース計画を定める
  • 予算を管理する
  • 顧客・プロダクトの利用者や組織の関連部署などの関係者と、プロダクトバックログの項目の内容を確認したり、順番、リリース時期を相談調整する
  • 既存のプロダクトバックログの内容を最新の状態にする
  • 関係者がプロダクトバックログについて理解できるように働きかける
  • プロダクトバックログが完成しているか確認する


プロダクトバックログの管理は開発チームと行うこともあるが、最終決定はあくまでPOが行います。これは、POが最終決定することで結果に対してPOが責任を持てることにつながります。

開発チーム

開発チームの主な役割は、プロダクトオーナーが順位付けしたプロダクトバックログの項目を順番に開発することです。

開発チームは通常3〜9名程度で構成され、3人未満の場合は、お互いの相互作用が少なかったり、個人のスキルに依存することが多くなてしまうため、スクラムでは推奨されていません。逆に10人以上になるとコミュニケーションコストが上がることで効率が落ちると言われています。

デザイナー、プログラマー、テスターなど、製品開発に必要なスキルを持つメンバーで構成され、肩書きやサブチームはありません。

スキルに差がある場合もありますが、作業を進めていく過程でなるべく個人が複数のことができるようになることが望ましいと言われています。

この部分に関してはチームの各メンバーの得意、不得意を把握して、「適材適所に人を割り当てる場面」「スキルの幅を増やすためにあえて挑戦する場面」の両面を意識して、チームを運営していく必要があるのだと想像しました。

開発チームの仕事の進め方は、開発チームのメンバーの合意のもとで進められ、外部から作業の進め方を指示されることはありません、プロダクトオーナーの部分で、「開発チームに相談はできるが、干渉はできない」と説明したのはこの部分になります。

あくまで開発チームは全体で責任を持って作業をすすめ、これを 自己組織化 と呼びます。開発チームが主体的に進めることで、開発チームの能力は継続的に向上していくことにつながります。

スクラムマスター

スクラムマスターは、スクラムプロセスがスムーズに進むよう支援し、チームの障害を取り除く役割。チームが高いパフォーマンスを発揮できるように促します。

プロダクトバックログをプロダクトオーナーが並び替え、開発チームがそれをもとに開発を進めます。そのプロセスを円滑にまわして、プロダクトを効率よくつくれるように支える役割が スクラムマスター です。

まさに「縁の下の力持ち」の存在だと言えます。

  • 仕組みがうまく回るように支援する
  • 障害の排除
  • 支援と奉仕
  • 教育・ファシリテーター・コーチ・進行役
  • マネージャーや管理者ではない(タスクのアサインも進捗管理もしない)


スクラムマスターは、ルールや作成物、進め方をPOや開発チームに理解させ、効率的な実勢を促しながら、スクラム外にいる人からの妨害や割り込みからチームを守ります。

チームがまだ、慣れていない間には、やり方を教える・イベントの司会進行をするなどトレーナー的な動きもしたりもします。チームの求めに応じて作業を助けたり、ヒントを与えるなどの動きも含まれるなど多岐にわたります。

スクラムマスターの動きの一例

  • PO・開発チームにアジャイルスクラムについて理解できるよう支援する
  • (必要時)スプリントプランニングやスプリントレトロスペクティブなどの司会進行
  • POと開発チームとの会話を促す
  • 生産性を高めるためにチーム・POに働きかける
  • プロダクトバックログなどの良い管理方法を提案する


スクラムマスターの役割は、チームの潤滑油的な役割を果たすポジションであることが伺えます。

想像するに、どうしてもプロダクトオーナーは開発の進行状況が気になり、開発チームは進行を気にしながらも開発で問題があると視野が狭くなり、チームだけでは問題を認識できない場面や、解決が難しいがでてくることが想像されます。

そんな場面でスクラムマスターが俯瞰してチーム全体を見て、うまくチームが回るように気づきを与えたり、改善を促すような提案をするなどの役割・立ち回りが必要なんだと感じました。

ここまででてきた、「プロダクトオーナー」「開発チーム」「スクラムマスター」を合わせて スクラムチーム と呼びます。

スクラムの5つの価値基準

スクラムを活用して良い結果を生むには、スクラムの5つの価値順を取り入れて実践していく必要があると言われています。

  • 確約:それぞれがゴールの達成に全力を尽くすことを確約する
  • 勇気:正しいことをする勇気を持ち、困難な問題に取り組む
  • 集中:全員がスプリントでの作業やゴールの達成に集中する
  • 公開:すべての仕事や問題を公開することに合意する
  • 尊敬:お互いを能力のある個人として尊重する


スクラムフレームワークを実行するだけでなく、それを効率よく活用するにはこれらの価値基準を踏まえて各個人が行動することが大切だと書かれています。

やはりどんな素晴らしいフレームワークであっても、人がフレームワークを活用します。

意見・相談を言いやすい雰囲気、チームで協力する姿勢、お互いをリスペクト持つなどのチーム状況でなければチームは成果をうまく出せないと思います。

スクラムのメリットを最大化し、良い成果を出すために、土台になる価値基準になると思うので、私自身しっかりを確認してチーム開発に臨みたいと思います。

【合格体験記】RubySilver試験の準備から合格までの体験談

はじめに

前提

まず前提として、この記事を書いているのは未経験からプログラミングに挑戦中の者になります。学習はフィヨルドブートキャンプ(以下 FBC)に参加しながら取り組んでいて、現役のエンジニアの方からレビューをもらいながら進めています。

現在の学習状況は以下を随時更新しているので興味ある方はご覧ください。

hirano-vm4.hatenablog.com

今回タイトルにもあるように、RubySilverに合格することができました!75点以上が合格で、今回の点数は92点でした。これから受ける方の参考になるかもしれないのでアウトプットしておきたいと思います。

受験動機

FBCでのプラクティスも終盤になり、残っている大きなプラクティスは「チーム開発」と「Webアプリ作成」になりました。

こちらの記事に記録したように、言語としてまずRubyフレームワークRailsを学習します。終了した後は、JavaScriptとReactと別の言語たちをしばらく学習していました。

その状態でいきなりチーム開発に入ってしまうとRubyに頭がすぐに切り替わらなそうだった。また、客観的な基準で一定のRubyの習熟度を確認しておきたいという気持ちがあってRubySilverを受験することにしました。


RubySilver試験とは

試験の概要と目的

公式(Ruby Association)では以下のように説明されています。

Ruby技術者認定試験制度は、Rubyベースのシステムを設計、開発、運用するエンジニア、Rubyでシステム提案を行うコンサルタントRubyを教える講師及びRubyを学ぶ学生などを対象とした認定試験制度です。認定者は、Ruby技術者としての技術力を公正に評価され、高い水準のRubyによるシステム開発能力を持つことを認定されます。

認定によりRubyベースでシステム開発を行ううえで必要な基礎的な知識と応用力をもつことをアピールすることができます。試験の合格者は、Rubyアソシエーションにより「 Ruby Association Certified Ruby Programmer Silver/Gold version 3」として認定されます。


この試験は、SilverとGoldの2つの試験があります。

Silverは、Rubyの文法知識、Rubyのクラスとオブジェクト、標準ライブラリの知識について、基本的な技術レベルを持つことを認定する試験。


Goldは、Silverで求められる範囲(文法、オブジェクト指向、組み込みライブラリ、実行環境など)を更に掘り 下げた知識に標準添付ライブラリ知識やアプリケーション設計に必要となるクラスやオブジェクトに関する知識を追加し、Rubyによるプログラム設計技術を持つことを認定する試験となっています。


なのでまずはSilverから受験するのが通常ルートだと思います。

「Goldとして認定されるにはGold及びSilver試験の合格が必要」という文言が公式にはあります。表現的に受験を妨げるものではないようにも捉えられますが、Goldだけを受験する場合は公式に問い合わせてみた方がよい気がしました(あまりそんな方はいらっしゃらないと思いますが)。


試験は90分で全50問です。選択肢を選んでいくのみなので、時間には余裕がありました。見直しを3回しても30分くらい余る感じでした。パソコンで試験を受験することになるので、当日操作に戸惑わないようにCBT体験版で予行練習しておきましょう!

マーカーを引いたり、選択肢を視覚的に絞れるように取り消し線をつけたり、あとで見直しができるようにフラッグを立てることができることがわかります。


これもプロメトリック社のサイト内で練習できるので不安な方は触っておきましょう。

試験結果は、受験後すぐに画面に表示されます。プロメトリック社で以下のように確認できました。

受験費用

受験費用はこの記事を書いている2024年2月時点で、通常価格16,500円(ガク割適用価格 8,250円)となっています。なかなか高額だったので、しっかり学習して大丈夫だと思える状態にしてから受験しました。

学生の方は半額で受験できるので卒業を控えている方は早めに応募したほうがお得に受験ができるかもしれません!


申し込み方法

Ruby Associationからではなく、受験の応募・支払い・会場の予約はプロメトリック社を通して行います。

少し応募やアカウントの取得にクセがあるので時間に余裕を持って手続きすることをお勧めします。

試験準備

勉強時間

日々の学習の中で問題を50問程度やって、間違った問題と疑問に感じた部分を自分でirbでコードを動かしてみたり、リファレンス、合格教本があるのでそれを確認しました。期間にしては隙間時間で1〜2ヶ月。試験前は1週間くらいからガッツリやりました。


学習教材

REx

rex.libertyfish.co.jp

こちらのWebアプリで無料で学習することができるので、まずはこちらのサイトで雰囲気を掴むのが良いかもしれません。平均して90点台を取れるまで反復しました。

GitHubアカウントを連携させるのみで利用することができます。解説もある程度書いていますが、省かれている部分もあるので、そこは自分でリファレンスやググり力でカバーしましょう!

今の時代ならChatGPTも学習に有効ですが、間違った回答がでてくることも多いので、最終的にはリファレンスの確認はしたほうがよいと思いました。


公式問題

Githubに公式の問題があるのでそれも無料でできます。また、さすが公式なだけあって似た問題も多かったような気がします。

Ruby技術者認定試験Silver模擬問題

こちらは旧バージョンの公式問題のようですが、やった方がいいと思います。


[改訂2版]Ruby技術者認定試験合格教本(Silver/Gold対応) Ruby公式資格教科書

https://amzn.to/48kZ2ERamzn.to

ここまで勉強して、RubySilverを受験しようと思った方は、この公式本を購入すると良いと思います。解説だけでなく、基礎問題や模擬問題もあってかなり似た問題が出題されていました。

この1冊でGoldもSilverも対応しているので少し高いですが、購入をお勧めします。知らなかったことが結構書かれていたので、試験が終わった後も辞書的に使えるかも?

注意した方がよさそうなのは[改訂2版]を購入するということです。口コミをみると初版はかなり間違いがあるようです。初版は安く中古で売っていますが、改訂2版の方が良さそうです。

私は改訂2版の紙の本が欲しかったのですが、あまり在庫がないのか探すのに苦労しました。たまたま良いタイミングで中古本が売られていたので、古本で購入しました。デジタル版はAmazonで購入可能でした。

受験した方のブログを読み漁る

たくさんの方がアウトプットされていて助かりました。同じFBCの方もいて嬉しくなりました。参考にした記事を以下に引用しておきたいと思います。ありがとうございました!

【Ruby】「!」が付かない破壊的メソッドまとめ #Ruby - Qiita

Ruby技術者認定試験Silver version 2.1を受けて… #Ruby - Qiita

【Ruby技術者認定試験】ポイントまとめ #Ruby - Qiita

Ruby Silverに合格しました! - すずかのプログラミング勉強記

Ruby Silver試験前に見直すと幸せになれるメモ - 気軽に楽しくプログラムと遊ぶ

模擬試験ガチで1問も解けなかった私がRuby Silverに合格したお話 - 宮水の日記

Ruby silverの試験勉強で、よくわからない部分を書き出してみた - 駆け出しエンジニアの気ままブログ

まったくの0からの学習でない場合はまず、テキストを読むのではなく問題を解く。そこから間違ったろころ、怪しい部分、疑問に感じたところをテキスト・リファレンス等で確認しておくのが効率の良い学習だと感じました。


試験で注意すべきポイント

受験して意識した方がよいポイントを箇条書きでまとめてみました。(全てではなく、覚えていたものを並べていますのでご注意ください)

  • 選択する対象が「正しいもの」or「間違っているもの」なのかを確認する

  • 選択すべき回答がいくつなのか確認:「1つ」「2つ」「複数」「すべて」など指示があるので確認を!たまに「すべて」とあっても1問のみだったりすることもあるので問題をまずしっかり読む(見直して気づいた問題がありました)

  • 練習問題の答えだけを学習しない(引数・オプション・破壊的メソッドか否かetc問題から考えられる周辺知識をirbなどで確認しておく)

  • 破壊的メソッドであるか否かで、変更が反映されていなかったor変更されていた問題が多い(!がなくても破壊的メソッドがあるので注意する)

  • 対象が見つからないときなどに、戻り値がエラーになるのか、nilなのか、0なのか、boolなのか、配列の要素数になるのか等

  • 比較演算子・論理演算子の戻り値・優先順位

  • 変数のスコープ

  • 正規表現を覚える

  • Dir、File、IOクラスのメソッド(pwdはDirクラスにあるかどうか等覚えておく)

  • Fileを開く際のモードの特徴を覚えておく(r r+ a a+ w w+  デフォルトは? ファイルポインターの位置の指定etc)

  • エイリアスメソッドは覚えておく!!

  • 例外処理(サブクラスまで補足する)

  • 進数の変換(080は8進数のためエラーになる、0xは16進数、0bは2進数など)

  • スーパークラス(指定しないとObjectクラスがデフォルトでスーパークラス

  • オブジェクト指向(initialize 継承 super attr_reader)

  • 文字列・配列・ハッシュなどのメソッドや要素の操作

  • 四則演算 優先順位

  • 比較の違い(== eql? equal? 同値なのか、同一なのか)

RubySilverのメリット・デメリット

Rubyの基礎的な知識が網羅的に学ぶことができるのがメリットだと感じました。

これまでRubyを学習してきましたが、課題で使う知識は一部です。これまで使わなかったけど、知っておくべきであろう知識も多くて個人的には勉強になりました。

どれくらい理解しているか客観的に測る指標ってなかなかありません。そういう意味でRubySilverを受験するメリットはあるのかな?と感じました。

デメリットは受験費用が高いことですかね(笑)試験と、教本の費用で2万円程度かかるので、人によってはデメリットに感じるかもしれません。個人的には自己投資としては高くは感じませんでした!

まとめ

以上、RubySilverの体験談でした。

年齢・環境・覚えの早さはそれぞれですが、自分なりに今の自分よりも1㎝ずつでもいいから、成長しようとする気持ちを持ち続けるって大切だなと感じました。

悩むこともあるけど、挑戦中の悩みって前進している証拠でもある(と自分に自己暗示)。

これからもいくつになっても、新しいことにチャレンジして変わっていける自分でいられるよう、引き続き好奇心持って努力していきたいと思います💪

FBCの学習が少し止まってしまったので、ここからはチーム開発、ポートフォリオになるアプリの作成に向けてギアを上げていきたいと思います🔥

また時間に余裕ができたらGoldもせっかくなので合格を目指したいと思います!ここまで目を通していただき、ありがとうございました!

余談

2月22日猫の日に合格できたのがちょっとだけ嬉しい。

【Ruby】String#splitメソッドの引数の使い方で混乱したポイントをまとめた

はじめに

前提

まず前提として、この記事を書いているのは未経験からプログラミングに挑戦中の者になります。学習はフィヨルドブートキャンプに参加しながら取り組んでいて、現役のエンジニアの方からレビューをもらいながら進めています。

現在の学習状況は以下を随時更新しているので興味ある方はご覧ください。

hirano-vm4.hatenablog.com

そのため、学んだことを不定期に初学者向けにアウトプットしています。

今回はRubySilverの勉強をしていた際に、String#splitメソッドの引数で少し混乱した部分があったので、改めて確認しました。せっかく調べたことをブログ記事に残したいと思います。

String#splitの基本的な使い方

Rubysplitメソッドは、文字列を指定した区切り文字で分割するために使用されます。以下に基本的な使い方です。

str = "apple,banana,grape"

arr = str.split(",") # => ["apple", "banana", "grape"]

この例では、splitメソッドは,を区切り文字として文字列strを分割し、結果として配列arrが生成されます。区切り文字は文字列内の任意の箇所で指定できます。

また、splitメソッドには2つ目の引数を渡すこともできます。この引数は、分割する部分の最大数を制限します。

str = "apple,banana,grape,orange"

arr = str.split(",", 2) # => ["apple", "banana,grape,orange"]

この例では、,を区切り文字として文字列strを最大2つの部分に分割しています。

これが、Rubysplitメソッドの基本的な使い方です。

今回混乱した問題はこちら

"a b c d".split()

"a\nb\nc\nd".split(//)

"a\tb\tc\td".split()

"a b c d".split(//)

「このコードのうち、実行した結果が同じものを2つ選べ」という問題です。

普段コードを書いていて\tなどのタブ文字を使ってこなかったので、回答に迷ってしまいました。

引数なしの場合

引数を指定しない場合、splitメソッドは空白文字(スペース、タブ、改行など)で文字列を分割。連続する空白文字は一つの区切りと見なされる。

"a b c d".split() # => ["a", "b", "c", "d"]

"a\tb\tc\td".split() # => ["a", "b", "c", "d"]

引数に正規表現または文字列を指定する場合

引数に正規表現または文字列を指定すると、そのパターンにマッチする部分で文字列を分割。

  • //(空の正規表現)を引数にすると、文字列を1文字ずつの配列に分割。
  • 文字列を引数にすると、その文字列で分割します。
"a\nb\nc\nd".split(//) # => ["a", "\n", "b", "\n", "c", "\n", "d"]
"a b c d".split(//) # => ["a", " ", "b", " ", "c", " ", "d"]

紛らわしい挙動まとめ

  • 空白文字で分割したい場合、引数なしでsplitを使うと自動的に空白文字(スペース、タブ、改行)で文字列を分割してくれる。
  • 文字列を1文字ずつ分割したい場合、引数に空の正規表現//を使用。
  • 特定の文字やパターンで分割したい場合、その文字列や正規表現を引数に指定。

問題の回答

よってこの問題の回答は以下のようになります

irb(main):203:0> "a b c d".split()
=> ["a", "b", "c", "d"]

irb(main):204:0> "a\nb\nc\nd".split(//)
=> ["a", "\n", "b", "\n", "c", "\n", "d"]

irb(main):205:0> "a\tb\tc\td".split()
=> ["a", "b", "c", "d"]

irb(main):206:0> "a b c d".split(//)
=> ["a", " ", "b", " ", "c", " ", "d"]

さいごに

結構、RubySilverの問題はメソッドの動きをしっかり理解していないと解けない絶妙なところを突いてくるので良い勉強になります!

また混乱した部分があればアウトプットしていきたいと思います。

【React】基本的なuseEffectの使い方と実用例

はじめに

前提

まず前提として、この記事を書いているのは未経験からプログラミングに挑戦中の者になります。学習はフィヨルドブートキャンプに参加しながら取り組んでいて、現役のエンジニアの方からレビューをもらいながら進めています。

現在の学習状況は以下を随時更新しているので興味ある方はご覧ください。

hirano-vm4.hatenablog.com

そのため、学んだことを不定期に初学者向けにアウトプットしています。

useEffectとは

ReactのuseEffectは、関数コンポーネント内で副作用(side effects)を扱うためのフック(Hooks)です。

副作用とは、データの取得、DOMの変更など、コンポーネントレンダリング結果に影響を与える操作のことを指します。

たとえば、DOMの更新後に特定の操作を実行したり、外部APIからデータをフェッチしたり、イベントリスナーを設定したりする場合などに利用されます。

基本的な使い方

// まずインポートする
import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  // コンポーネントがレンダリングされるたびに実行されます
  useEffect(() => {
    document.title = `クリック回数: ${count} 回`;
  });

  return (
    <div>
      <p>クリック回数: {count} 回</p>
      <button onClick={() => setCount(count + 1)}>
        クリック
      </button>
    </div>
  );
}

この例では、useEffect内でドキュメントのタイトルを更新しています。useEffectに渡された関数は、コンポーネントの初回レンダリング後と、その後の各レンダリング後に実行されます。

依存配列(Dependency Array)

useEffect第二引数に空の配列([])を渡すと、副作用はコンポーネントの初回レンダリング時にのみ実行され、その後は実行されません。

配列内に特定の状態やプロップスを指定すると、その値が変更された時のみ副作用が実行されます。

useEffect(() => {
  console.log('この副作用は初回レンダリング時にのみ実行されます');
}, []); // 空の依存配列

useEffect(() => {
  console.log(`countが更新されました: ${count}`);
}, [count]); // countのみを依存配列に指定

依存配列の例

0. 第二引数に何も指定しなかった場合

依存配列を省略すると、コンポーネントレンダリングされるたび(状態やpropsが更新されるたび)に副作用が実行されます。

useEffect(() => {
  // この副作用はコンポーネントのレンダリング後に毎回実行されます。
});

ただし、多くの場合、パフォーマンスの観点から無駄な再実行を避けるために、依存配列を適切に設定することが推奨されるようです。

1. 空の配列を指定した場合

先ほど記述したように第2引数に空の配列を設定した場合は、初回のレンダリング後に1回だけ実行されます。

useEffect(() => {
  console.log('コンポーネントがマウントされた時に一度だけ実行されます');
}, []);

この場合、副作用はコンポーネントがマウントされた時に一度だけ実行され、アンマウント時や値の更新時には実行されません。

APIからデータを取得する、イベントリスナーを設定する、タイマーを設定するなど、コンポーネントのライフサイクル中に一度だけ行いたい操作に適しているようです。

2. 依存配列に値を指定した場合

const [count, setCount] = useState(0);

useEffect(() => {
  console.log(`countが更新されました: ${count}`);
}, [count]);

この場合、countの値が変更されるたびに副作用が実行されます。count以外の状態が変更されても副作用は実行されません。

useEffectの実用例

基本的効果は分かりましたが、どんな場面でどう使うのかがイメージがつかなかったので少し調べてみました。

実用例①データフェッチング

APIからデータをフェッチしてコンポーネントに表示する場合、useEffectを使用してデータの取得を行います。これにより、コンポーネントが画面に表示された直後にデータがロードされます。

function App() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => setData(data));
  }, []); // 空の依存配列を渡すことで、コンポーネントのマウント時にのみ実行されます

  return (
    <div>
      {data ? <div>{data.name}</div> : 'Loading...'}
    </div>
  );
}

実用例②イベントリスナーの設定とクリーンアップ

ウィンドウサイズの変更やキーボードイベントなど、特定のイベントに対するリスナーを設定する場合にuseEffectが役立つ。

また、コンポーネントのアンマウント時にこれらのイベントリスナーをクリーンアップ(削除)することも重要。

function App() {
  useEffect(() => {
    const handleResize = () => console.log('Window resized');
    window.addEventListener('resize', handleResize);

    // クリーンアップ関数
    return () => window.removeEventListener('resize', handleResize);
  }, []); // 空の依存配列

  return <div>Hello World</div>;
}

実用例③外部ライブラリの統合

DOM要素に対して外部ライブラリ(例えば、チャートライブラリやスライダーライブラリ)を適用する場合、useEffect内でライブラリの初期化コードを実行します。

レンダリング後にDOMが準備完了していることを保証するためにuseEffectを使用します。

function Chart() {
  useEffect(() => {
    // Chart.jsの初期化など
    const ctx = document.getElementById('myChart').getContext('2d');
    new Chart(ctx, {
      // Chart.jsの設定
    });
  }, []);

  return <canvas id="myChart"></canvas>;
}

実用例④ タイマーの設定

setTimeoutsetIntervalを使って、一定時間後に何かを実行する。

useEffect(() => {
  const timerId = setTimeout(() => {
    console.log('このメッセージは3秒後に表示されます');
  }, 3000);

  return () => clearTimeout(timerId); // タイマーをクリア
}, []); // 空の依存配列を使用

副作用が特定の条件(初回マウント時、特定の依存値の変更時など)でのみ実行されるように、依存配列を適切に使用することにより、不要な副作用の実行を防ぎ、パフォーマンスを最適化することができる。

使用するにあたって注意すべき点

使うにあたって注意すべき点についても調べてみました

①useEffect に渡すコールバック関数を Promise にしてはいけない

useEffectに非同期関数を直接渡すことは推奨されていないとのことです。

これは、useEffect のコールバック関数が戻り値としてクリーンアップ関数を期待しているのが理由のようです。非同期関数は Promise を返すため、そのため期待した動きにならなくなります。

非同期処理をuseEffect内で扱う正しい方法は、コールバック関数内で非同期関数を定義し、それを直接呼び出すことです。

間違った使用例:

useEffect(async () => {
  const response = await fetch('https://api.example.com/data');
  console.log(response);
}, [query]);

上記のコードは、useEffect のコールバック関数として非同期関数を直接渡している。結果、この非同期関数は Promise を返すため、useEffect の期待するクリーンアップ関数を返していない例となる。

正しい使い方は、useEffect のコールバック関数の内部に非同期関数を定義し、呼び出すようにしてあげる。

正しい使用例:

import React, { useEffect } from 'react';

const SimpleExample = () => {
  useEffect(() => {
    // 非同期関数を定義
    const fetchData = async () => {
      try {
        const response = await fetch('https://api.example.com/data');
        const data = await response.json();
        console.log(data);
      } catch (error) {
        console.error('Fetching data failed', error);
      }
    };

    // 非同期関数を呼び出し
    fetchData();
  }, []); // 空の依存配列を指定して、コンポーネントのマウント時に1回だけ実行されるようにする

  return <div>Check the console for data.</div>;
};

このコードでは、useEffect フックの内部で非同期関数 fetchData を定義し、即座にそれを呼び出している。

依存配列 [] が空なので、この useEffect フックはコンポーネントの初回マウント時に1回だけ実行される。

fetchData 関数内では、非同期にデータをフェッチし、成功した場合は結果をコンソールに出力し、エラーが発生した場合はエラーメッセージをコンソールに出力されます。

②不必要な再レンダリングの引き起こし

useEffect内でステートを更新すると、そのコンポーネントが再レンダリングされます。依存配列を正しく設定しないと、無限ループに陥ることがある。

誤った例:

function MyComponent() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setCount(count + 1); // これにより再レンダリングがトリガーされる
    // 依存配列に何も指定していないため、再レンダリングの度に実行される
  });
}

使っていく中でまた、気づいたことがあれば追記していきたいと思います!

さいごに

Reactのチュートリアルで学習を進めていく中で、いまいちどんな場面でuseEffectを使うの分からなかったので調べたので、ブログにもまとめてみました。

私も学習中のみなので、レベルが上げて、また新しい発見があれば発信していきたいと思います。

【npmリリース】約2400種類の仮想通貨の価格情報をターミナルで取得できるnpmを公開しました

coinrateとは

coinrate は、暗号資産市場全体の市場取引情報や各銘柄の詳細な取引データをターミナル上で簡単に取得できるコマンドラインツールです。ターミナルを通じて、リアルタイムの市場の価格変動、銘柄ごとの価格情報へのアクセスが可能です。

このツールは、迅速かつ効率的な情報収集を可能にします。約 2400 種類の暗号資産銘柄に対応し、 トップに表示されていない銘柄については Ticker で検索が可能です。


公開先

github.com

www.npmjs.com


作った経緯

私は2022年5月から未経験スタートでプログラミングの学習をしています。

学習はフィヨルドブートキャンプ(以降 FBC)のコミュニティ(受け身で学ぶスクールではなく、自走に近い形で進めていく人たちの集まりのため、あえてコミュニティとします)に参加していて、現役のエンジニアの方からレビューをもらいながら進めています。

現在の学習状況は以下を随時更新しているので興味ある方はご覧ください。

hirano-vm4.hatenablog.com

FBCJavaScriptのプラクティスの最後の課題は、「npm パッケージの作成」となっています。自分でテーマを考えてnode.jsでnpmを作り、それだけでなく実際に公開するところまでが終了要件です。

このプラクティスの一貫でcoinrateを作成しました。

当初、何を作ろうかかなり迷いました。

考え抜いた結果、私は仮想通貨に限らず投資が趣味だったので「投資に役立つ実用的なnpmを作ってみたい」という想いから、ターミナルでサッと必要な仮想通貨のデータを取得できるnpmを作ることにしました。

投資の中でも仮想通貨をテーマにあげた理由は3つあります。

ブロックチェーンに興味があってノードの運用をしていた

学習と並行して、元々ブロックチェーンにも興味があってブロックチェーンのノードをVPSに構築して運用・保守も始めました。

campfire-stake-pool.com

なので自分が興味があることで実用的なものを作ってみたかったのが理由の1つです。

②自分の怠惰な気持ちが需要になるかなと考えた

そんな感じなのでプログラミングの学習中もついつい値動きが気になってしまうことがあります(笑)

ブラウザで検索して価格を表示するのが面倒に感じることがあったのでターミナルで価格がサッと確認できたら便利だな〜という怠惰な気持ちからテーマを決めました(この怠惰が需要になるかな〜と淡い期待)。

そしてブラウザでサイトを見始めると脱線して学習が滞ってしまいがち(自分の問題)。そんなときにターミナルで完結すれば手早く、必要な情報だけ取得できて脱線しにくくなる、、、はずです。

③まだ新しい技術でライバルが少ない

あと仮想通貨(暗号資産)の分野だとまだテーマにするが人が少ないことで需要をとれるかなと考えてみました。

npmなので、これはあまり関係ないかもしれませんが、正式にウェブアアプリを近い将来ポートフォリオとして作るので、その時のテーマ決めの練習にもなるのでは?と考えてみました。

なのでREADMEも含めてしっかり作りました。

特徴

  • 暗号資産市場全体の市場取引情報の取得
  • 約 2,400 種類の暗号資産銘柄に対応(CoinloreAPI を使用)
  • フリーで解放されているAPIを使用しているため、個別にキーの取得は不要ですぐに利用可能
  • ティッカー検索


前提条件

coinrate をインストールする前に、以下の前提条件がシステムに満たされていることを確認してください:

  • Node.js: システムに Node.js がインストールされている必要があります。coinrate に必要なバージョンは 10.0.0 以上です。Node.js はNode.js 公式ウェブサイトからダウンロードしてインストールできます。 さらに、coinrate は以下の Node.js パッケージに依存しており、ツールをインストールする際に自動的にインストールされます:

  • axios(バージョン 1.6.2 以上): 暗号通貨データの取得に使用する HTTP リクエストを行うために使用されます。

  • cli-table2(バージョン 0.2.0 以上): ターミナルでのテーブル表示に利用されます。
  • enquirer(バージョン 2.4.1 以上): 対話型コマンドラインインターフェースに使用されます。 ここに挙げられているものを除いて、coinrate を実行するために特定のソフトウェアやライブラリが必要とされることはありません。インストールに進む前に、Node.js 環境が正しくセットアップされていることを確認してください。


使用方法

npx を利用して、mycrypto を実行します。

$ npx coinrate

必要に応じてローカル環境にクローンし、実行ファイルmain.js$ node main.jsで実行してください。


表示データの説明

coinrate は、暗号通貨の詳細な取引情報表にして提供します。以下は、テーブルの各行で提供される情報の概要です:

市場全体の概要

タイトル 説明
Price Checked At 情報を取得した日時。形式: YYYY/MM/DD HH:MM:SS
Total Market Cap 市場全体の暗号通貨の総時価総額
Market Cap Change (24h) 過去 24 時間での市場全体の時価総額の変動率
Total Volume 市場全体の暗号通貨の総取引量
Volume Change (24h) 過去 24 時間での市場全体の取引量の変動率
Bitcoin Market Dominance ビットコインが市場全体の時価総額に占める割合
Ethereum Market Dominance イーサリアムが市場全体の時価総額に占める割合
All-Time High Volume 市場全体の暗号通貨で記録された史上最高の取引量
All-Time High Market Cap 市場全体の暗号通貨で記録された史上最高の時価総額


個別通貨情報

タイトル 説明
Price Checked At 情報を取得した日時。形式: YYYY/MM/DD HH:MM:SS
Currency Name 暗号通貨の名前、例: Bitcoin
Ticker Symbol 暗号通貨の市場シンボル、例: BTC
Market Cap Rank 時価総額における暗号通貨のランク
Price 暗号通貨の現在価格、$43,376.11/BTC として表示
Price Change (1h) 過去 1 時間の価格変動率
Price Change (24h) 過去 24 時間の価格変動率
Price Change (7d) 過去 7 日間の価格変動率
Market Cap 暗号通貨の総時価総額
Volume (24h) 過去 24 時間の暗号通貨の総取引量
Circulating Supply 現在流通している暗号通貨の総量
Total Supply 利用可能な暗号通貨の総量


使用例

市場全体の概要を取得

Cryptocurrency Market Overviewを選択
市場全体の概要

個別の暗号資産の情報を取得

トップに表示されるティッカーを選択
市場全体の概要


ティッカーで検索して情報を取得

Other (Ticker Search)を選択
ティッカーで検索


カスタマイズ

表示するテーブルのデザインを変更する場合

テーブルはcli-table2を使用しています。 変更する場合は、cli-table2を参考にCryptoTableクラス(crypto_table.js)を変更してください。


デフォルトで表示されるティッカーを追加・削除する場合

変更する場合は、config/constants.jscryptoChoicesの配列を変更してください。


ライセンス

このソフトウェアは、MIT ライセンスの下で公開されています。LICENSE.txt を参照してください。

さいごに

coinrateを作るまで2回くらいしかJavaScriptをまともに書いたことがなかったので、このnpm作成という実践を通じて学びが大きかったと感じています。

ただコードを書くだけでなくオブジェクト思考でクラスを分ける、命名をわかりやすいものにする、の重要性を改めて感じると同時に難しさを痛感しました。

1000時間を超える時間を費やしましたが全然足りない部分が多いので、引き続きコツコツ学習を継続していきたと思います!

JavaScriptで日付・時刻・曜日を扱う方法【Dateオブジェクト】

はじめに

前提

まず前提として、この記事を書いているのは未経験からプログラミングに挑戦中の者になります。学習はフィヨルドブートキャンプに参加しながら取り組んでいて、現役のエンジニアの方からレビューをもらいながら進めています。

現在の学習状況は以下を随時更新しているので興味ある方はご覧ください。

hirano-vm4.hatenablog.com

筆者は執筆時点で、RubyRuby on Rails)のプラクティスが終わったあとにJavaScriptに取り組んでいるので、完全に0からではありません。JavaScriptを多言語から学ぶにあたって、まず覚えるべき要点をまとめました。

詳しい解説ではなく要点をまとめた学習記録・ノートになりますのでご注意ください。

記事の本体は以下にになります。長くなってしまったので別記事として書いているものとなります。ご注意ください。

hirano-vm4.hatenablog.com

Dateオブジェクト

JavaScriptにはDateオブジェクトが用意されている。日付や時刻を扱うことができる。 インスタンスを作成すると特定の日時を表す値を持つ(この値は内部的には 1970 年 1 月 1 日 0 時 0 分 0 秒 UTC からの経過ミリ秒という形式で保管されている)。

developer.mozilla.org

Dateオブジェクトのインスタンスを作成

Dateオブジェクトのコンストラクタの種類

Dateオブジェクトのインスタンスを作成するにはコンストラクタを使用する。4種類のコンストラクタがしようできる。

現在日時のDateオブジェクトのインスタンスを作成

引数を指定せずに Date オブジェクトのインスタンスを作成すると、現在の日時の値を持つインスタンスを作成する。

new Date()

let d = new Date();

console.log(d.toString());
// Tue Nov 07 2023 21:18:56 GMT+0900 (日本標準時)

console.log(d.toUTCString());
// Tue, 07 Nov 2023 12:18:56 GMT

経過ミリ秒を指定してDateオブジェクトのインスタンスを作成

基準日時 1970 年 1 月 1 日 0 時 0 分 0 秒 UTC からの経過ミリ秒を指定して Date オブジェクトのインスタンスを作成する。 new Date(経過ミリ秒数)

  • 引数に指定した基準日時からの経過ミリ秒数で表される日時の値を持つ Date オブジェクトのインスタンスを作成する
  • このコンストラクタでは UTC からの経過ミリ秒で日時を指定するため、タイムゾーンについて考慮する必要がない
let day = new Date(10000);
console.log(day.toUTCString());
// Thu, 01 Jan 1970 00:00:10 GMT
日時を表す文字列を指定してDateオブジェクトのインスタンスを作成

日時を表す文字列を指定して Date オブジェクトのインスタンスを作成する。タイムゾーンを指定しなかった場合は、ローカルの環境で設定されているタイムゾーンでの日時が指定されたものとをして扱われる。

new Date(日付と時刻を表す文字列)

let d1 = new Date("2023-11-07T21:48:15");
console.log(d1.toString());
// Tue Nov 07 2023 21:48:15 GMT+0900 (日本標準時)

let d2 = new Date("2023-11-07");
console.log(d2.toString());
// Tue Nov 07 2023 09:00:00 GMT+0900 (日本標準時)

let d3 = new Date("2023-11-07T21:48:15Z");
console.log(d3.toString());
console.log(d3);
// Wed Nov 08 2023 06:48:15 GMT+0900 (日本標準時)
// 2023-11-07T21:48:15.000Z

年/分などを数値で指定してDateオブジェクトのインスタンスを作成

年、月、日、時、分、秒、ミリ秒の数値を指定してDateオブジェクトを作成する。 new Date(年, 月 [, 日 [, 時 [, 分 [, 秒 [, ミリ秒]]]]])

  • 年と月については必須の項目(それ以外は省略できる:省略した場合、日は 1 に、それ以外の 時、分、秒、ミリ秒は 0 が設定される)
  • 年は 4 桁or2 桁で指定(2 桁で指定した場合は 1900 + 年 となる)
  • 月は 0 から 11 の値で指定(1月が0、12月が11)
  • 年月だけで日付を指定しないと1日になる
let d1 = new Date(2023, 11);
console.log(d1.toString());
// Fri Dec 01 2023 00:00:00 GMT+0900 (日本標準時) 日付はしていないと1日になる

let d2 = new Date(10, 11, 31);
console.log(d2.toString());
// at Dec 31 1910 00:00:00 GMT+0900 (日本標準時) 11は12月を指す

let d3 = new Date(2023, 7, 31, 12, 30, 1, 110);
console.log(d3.toString());
// Thu Aug 31 2023 12:30:01 GMT+0900 (日本標準時)

コンストラクタをnew演算子をつけずに呼びだした場合

現在の日時を表す文字列を返す

let today = Date();
console.log(today.toString());
// Tue Nov 07 2023 21:44:14 GMT+0900 (日本標準時)

Dateオブジェクトの値を文字列で取得

日付と時刻を文字列として取得する(toString)

  • toString メソッドは、 Date オブジェクトが持つ日付と時刻の値を文字列として返す
  • タイムゾーンはローカルの環境で設定されているタイムゾーンが使用される

Dateオブジェクト.toString()

let today = new Date();
console.log(today.toString());
// Tue Nov 07 2023 21:44:14 GMT+0900 (日本標準時)

日付を文字列として取得する(toDateString)

  • toDateStringメソッドは、Dateオブジェクトが持つ日付の値を文字列として返す Dateオブジェクト.toDateString()
let today = new Date();
console.log(today.toDateString());
// Tue Nov 07 2023

時間は表示されなくなる。

時刻を文字列として取得(toTimeString)

  • toTimeString メソッドは、Dateオブジェクトが持つ時刻の値を文字列として返す
let today = new Date();
console.log(today.toTimeString());
// 21:54:12 GMT+0900 (日本標準時)

時間だけが返ってくる。

UTCタイムゾーンとして日付と時刻を文字列として取得(toUTCString)

  • toUTCString メソッドは、Dateオブジェクトが持つ日付と時刻の値を文字列として返す
  • タイムゾーンUTC が使用される
let today = new Date();
console.log(today.toUTCString());
// Tue, 07 Nov 2023 12:57:48 GMT

UTCタイムゾーンとして日付と時刻(ミリ秒含)を文字列として取得(toJSON)

  • toJSON メソッドは、Dateオブジェクトが持つ日付と時刻の値を文字列として返す
  • タイムゾーンUTC
let today = new Date();
console.log(today.toJSON());
// 2023-11-07T12:59:36.326Z

Dateオブジェクトの値を指定のロケール形式にした文字列で取得

日付と時刻を指定したロケールの形式で文字列として取得(toLocaleString)

  • toLocaleString メソッドは、Date オブジェクトが持つ日付と時刻の値を文字列として返す
  • ロケールを省略した場合はブラウザに設定されているロケールを使用

Dateオブジェクト.toLocaleString([ロケール[, オプション]])

let today = new Date();

console.log(today.toLocaleString("en-US"));
// 11/7/2023, 10:02:57 PM

console.log(today.toLocaleString("ja-JP"));
// 2023/11/7 22:02:57

console.log(today.toLocaleString());
// 2023/11/7 22:02:57 指定しないとローカルの設定と同じ

日付を指定したロケールの形式で文字列として取得(toLocaleDateString)

  • toLocaleDateString メソッドは、Dateオブジェクトが持つ日付の値を文字列として返す こちらは時間はなく年月日のみ
  • ロケールを省略した場合はブラウザに設定されているロケールを使用

Dateオブジェクト.toLocaleDateString([ロケール[, オプション]])

let today = new Date();

console.log(today.toLocaleDateString("en-US"));
// 11/7/2023
console.log(today.toLocaleDateString("ja-JP"));
// 2023/11/7

console.log(today.toLocaleDateString());
// 2023/11/7 指定しないとローカルの設定と同じ

時刻を指定したロケールの形式で文字列として取得(toLocaleTimeString)

  • toLocaleTimeString メソッドは、Dateオブジェクトが持つ時刻の値を文字列として返す こちらは時間のみ
  • ロケールを省略した場合はブラウザに設定されているロケールを使用

Dateオブジェクト.toLocaleTimeString([ロケール[, オプション]])

let today = new Date();

console.log(today.toLocaleTimeString("en-US"));
// 10:02:57 PM

console.log(today.toLocaleTimeString("ja-JP"));
// 22:02:57

console.log(today.toLocaleTimeString());
// 22:02:57 指定しないとローカルの設定と同じ

Dateオブジェクトの値を基準時間からの経過ミリ秒の値で取得

日付と時刻を経過ミリ秒の値として取得(getTime)

  • getTime メソッドは、Date オブジェクトが持つ日付と時刻の値を基準日時からの経過ミリ秒の値として返す

Dateオブジェクト.getTime()

let day = new Date(2000);

console.log(day.getTime());
// 2000 基準時間からの経過ミリ秒を取得

let today = new Date();

console.log(today.getTime());
// 1699362959811 Date オブジェクトが持つ日付と時刻の情報を基準時間からの経過秒数の値として取得

曜日を取得

  • Javascriptを使って曜日を取得するには、Dateオブジェクトに対してgetDay()メソッドを使う Dateオブジェクト.getDay())
  • getDay()メソッドはその曜日に応じて “0〜6” の数値を返す
  • 0を日曜日で、6は土曜日となる
曜日
日曜日 0
月曜日 1
火曜日 2
水曜日 3
木曜日 4
金曜日 5
土曜日 6

なので配列で各曜日の文字列を作って置き換える作業が必要になる。

const days = [
  "日曜日",
  "月曜日",
  "火曜日",
  "水曜日",
  "木曜日",
  "金曜日",
  "土曜日",
];
const today = new Date();

console.log(days[today.getDay()]);

// 火曜日(実行した曜日が表示される)

日付と時刻の値を取得するメソッドの一覧

Date オブジェクトが持つ値から以下のメソッドを使って様々な値を限定して取得することができる(ローカルの環境で設定されているタイムゾーンが使用される)。

各メソッドのgetあとにUTCをつけるとUTCタイムゾーンの値も取得可能(例:getUTCDay

メソッド 動作
getFullYear 年の値を取得する
getMonth 月の値を取得する
getDate 日の値を取得する
getHours 時の値を取得する
getMinutes 分の値を取得する
getSeconds 秒の値を取得する
getMilliseconds ミリ秒の値を取得する

月の値を取得する(getMonth)

  • Date オブジェクトが持つ日付と時刻の値からローカルのタイムゾーンでの「年」の値を数値で返す
  • 月の値を 0 から 11 の数値で返します。 0 が 1 月、 1 が 2月、 11 が 12 月に相当ので注意 Dateオブジェクト.getFullYear()

日の値を取得する(getDate)

  • Date オブジェクトが持つ日付と時刻の値からローカルのタイムゾーンでの「日」の値を数値で返す

Dateオブジェクト.getDate()

時の値を取得する(getHours)

  • Date オブジェクトが持つ日付と時刻の値からローカルのタイムゾーンでの「時」の値を数値で返す
  • 時の値を 0 から 23 までの数値で返す Dateオブジェクト.getHours()

分の値を取得する(getMinutes)

  • Date オブジェクトが持つ日付と時刻の値からローカルのタイムゾーンでの「分」の値を数値で返す

Dateオブジェクト.getMinutes()

秒の値を取得する(getSeconds)

  • Date オブジェクトが持つ日付と時刻の値からローカルのタイムゾーンでの「秒」の値を数値で返す Dateオブジェクト.getSeconds()

ミリ秒の値を取得する(getMilliseconds)

  • Date オブジェクトが持つ日付と時刻の値からローカルのタイムゾーンでの「ミリ秒」の値を数値で返す Dateオブジェクト.getMilliseconds()

月の初日(1日)と月末の日にちを取得する

月(コード実行日の属する月)の初日の場合

let today = new Date();

let firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(),1);

まず、new Date()で実行したその時のDateオブジェクトを作成し変数に入れる。その変数を使って新しいDateオブジェクトを作成する。

引数に(today.getFullYear(), today.getMonth(),1)とすることでその日の年・月が入る。月初めは常に1日なので1が入る。月に関しては1月が0になるので、表示上は+1する必要がある

月(コード実行日の属する月)の最終日の場合

上記と同じ容量で引数の日にちの部分を0とすることで最終日が取得できる。ただし0とすると前月の末日が表示されるため、今月の場合は月に+1、翌月の場合は月に+2する必要がある。

前月の最終日
let today = new Date();

let lastDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 0) 

// Tue Oct 31 2023 00:00:00 GMT+0900 (日本標準時)
今月の最終日
let today = new Date();

let lastDayOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0) 

// Thu Nov 30 2023 00:00:00 GMT+0900 (日本標準時)
翌月の最終日
let today = new Date();

let lastDayOfMonth = new Date(today.getFullYear(), today.getMonth() + 2, 0) 

// Sun Dec 31 2023 00:00:00 GMT+0900 (日本標準時)

Dateオブジェクトの値に年、月、分、秒などの新しい値を設定

Date オブジェクトが持つ値に対して日付と時刻の値をそれぞれ設定するメソッドが用意されている。

日付と時刻の値を設定するメソッド一覧

各メソッドのgetの後にUTCをつけると、UTCタイムゾーンで設定され(例:setUTCFullYear)、そうでない場合はローカル環境に設定されているタイムゾーンとなる。

メソッド 動作
setFullYear 年の値を設定する
setMonth 月の値を設定する
setDate 日の値を設定する
setHours 時の値を設定する
setMinutes 分の値を設定する
setSeconds 秒の値を設定する
setMilliseconds ミリ秒の値を設定する

let today = new Date();
console.log(today.toString());
// Tue Nov 07 2023 23:18:39 GMT+0900 (日本標準時)

today.setFullYear(2000);
console.log(today.toString());
// Tue Nov 07 2000 23:18:39 GMT+0900 (日本標準時) 年だけ変わっている

today.setFullYear(1999, 11, 20);
console.log(today.toString());
// Mon Dec 20 1999 23:18:39 GMT+0900 (日本標準時)

秒だけ、日にちだけなどに合わせてメソッドを使い分ける。

ローカルとUTCタイムゾーンの差を取得する(getTimezoneOffset)

let today = new Date();
console.log(today.toString());
// Tue Nov 07 2023 23:24:05 GMT+0900 (日本標準時)

console.log(today.getTimezoneOffset());
// -540

Dateオブジェクト.getTimezoneOffset()