Laravel – 例題 – Rock-Paper-Scissors

概要

LaravelのToy problemとして、簡単なじゃんけんのアプリケーションを作る。

  • 初期画面にRock/Paper/Scissorsの3つのラジオボタンと”Match!”ボタンを表示
  • ユーザーがラジオボタンのいずれかを選択して”Match!”ボタンを押すと、コンピューター側の手をランダムに発生させて勝敗比較
  • ユーザー/コンピューターの名前と手、結果を表示に加えて再表示

ユーザー、コンピューターのオブジェクトを生成するPlayerクラスを作成する。

また、手の値のバリデーションは行っていない。

Playerクラス

ユーザー/コンピューターに関わらず、プレーヤーの名前と現在の手(Rock/Paper/Scissors)を保持し、勝ち負け・あいこの判定機能を備えるクラス。

クラスファイルはpublic下のサブディレクトリ―に置く

  • クラスファイルの配置はpublic/rock_paper_scissors/Player.php
  • コントローラーなどからアクセスする場合、public_path()を使う

クラスの仕様は以下の通り。

  • 名前空間を含むフルパスのクラス名はrock_paper_scissors\Player
  • このクラスからユーザーとコンピューターそれぞれのインスタンスを生成
  • Playerのプロパティーは名前($name)とじゃんけんの手($hand_number)
  • $hand_numberは0: rock、1: paper、2: scissorsに対応
  • $hand_numberは外部からpublicメソッドで設定
  • $hand_numberに対応した手の名称をクラス定数の配列として準備し、現在の手の名前を返すメソッドを準備
  • 自身が他のPlayerに対して勝っているか(wins)、あいこか(draws)を判定するメソッドをそれぞれ準備

ルーティング

ルーティングはGETメソッドとPOSTメソッドに対応して2つ。

コントローラー

コントローラーのアクションは、GETに対する初期ページへの遷移と、POSTに対する処理・遷移の2つ。

ビュー

GETの場合はフォームだけ表示し、POSTでじゃんけんを実行したときには結果も表示する。

実行結果

初期表示

Rock-Paper-Scissors

  

 

結果表示

Rock-Paper-Scissors

  


User

  1. Name: USER
  2. Hand: Rock

Computer

  1. Name: COM
  2. Hand: Paper

Result

Computer won

 

PHP – SplFileObject::setFrags()

概要

PHPのSplFileObjectのフラグがわかりにくかったので整理した。確認したバージョンは以下の通り。

  • OS: Vagrant/VirtualBox/CentOS7
  • PHP: 7.3.28
  • Laravel: 6.20.29

フラグ詳細

\SplFileObject::READ_CSV

行読込の際、CSV列として解釈する。
\SplFileObject::READ_AHEAD
日本語・英語のどのサイトでもマニュアル記述そのままに”先読み/巻き戻しで読み込む”としか書いていない。SKIP_EMPTYなどの処理のためにバッファリングして、処理が行われた場合に巻き戻すという意味か。
\SplFileObject::SKIP_EMPTY
空行が無視される。改行コードのみの行は空行とは認識されず削除対象とならないが、DROP_NEW_LINEと組み合わせることで空行がスキップされる。
\SplFileObject::DROP_NEW_LINE
改行文字が無視される。ダブルクォートで囲んだ項目中に改行文字がある場合も、改行文字が削除される。たとえば以下の様にフィールドの途中に改行を入れたり、空行がある場合、DROP_NEW_LINEにより宮城県と仙台市の間の改行が除かれ、”宮城県仙台市”とつなげられる

テキストファイル読み込み時

概要

以下のようにテキストファイルを扱いたい場合。

  • 改行コードは取り除きたい
  • 空行は読み飛ばしたい

このような場合、SplFileObjectのインスタンスに対して以下のようにフラグ設定する。

改行コードは取り除きたいが空行は空行のままで残したい場合はDROP_NEW_LINEのみ設定し、READ_AHEADはあってもなくてもよい。ただし最後の行の次に空行が付いてきてしまう。

テスト用ファイル

以下のテキストファイルで確認した。エンコーディングはUTF-8で最後の行や空行も含めて各行末のコードはLF

テスト用コード

  • コントローラーでファイルを読み込み、行単位で配列に格納
  • dd()で配列の内容を確認(returnは実行されない)
  • setFlags()の引数を変化させて結果を比較

結果

フラグ設定なしの場合

setFlags()の行をコメントアウトし、フラグ設定なしで実行した場合。

  • 改行コードが残る
  • 最終行の後に空文字列("")が付いてくる

SKIP_EMPTYのみを設定した場合

  • 改行コードが残る
  • 最終行の後にbooleanfalseが付いてくる

DROP_NEW_LINEのみを設定した場合

  • 改行コードは取り除かれる
  • 改行のみの空行は空文字列になる
  • 最終行の後に空文字列が付いてくる

SKIP_EMPTY | DROP_NEW_LINE

  • 改行コードは取り除かれる
  • 空行は取り除かれる
  • 最終行の後にbooleanfalseが付いてくる

READ_AHEAD | SKIP_EMPTY

  • 改行コードは残る
  • 空行は残る
  • 最終行の後には何も付かない

READ_AHEAD | DROP_NEW_LINE

  • 改行コードは取り除かれる
  • 改行のみの空行は空文字列になる
  • 最終行の後に空文字列が付けられる

READ_AHEAD | SKIP_EMPTY | DROP_NEW_LINE

  • 改行コードは取り除かれる
  • 改行のみの空行は取り除かれる
  • 最終行の後には何も付かない

CSVファイル読み込み時

概要

以下のようにCSVファイルを読み込みたい場合。

  • 空行はスキップしたい
  • フィールド中の改行は取り除きたい

このような場合、SplFileObjectのインスタンスに対して以下のようにフラグ設定する。

空行はスキップするがフィールド中の改行は残したい場合、フラグの設定だけでそのような結果を得ることはできないようである。

READ_CSVのみ設定し、内容がnullのデータを登録せずに飛ばしていくことになる。

テスト用ファイル

テスト用コード

結果

READ_CSVのみの場合

  • 空行に対応してnullの要素が残る
  • フィールド中の改行は残る
  • 最終データの後にnullの要素が付く

SKIP_EMPTYを追加

  • 空行に対応してnullの要素が残る
  • フィールド中の改行は残る
  • 最終データの後にfalseの要素が付く

DROP_NEW_LINEを追加

  • 空行に対応してnullの要素が残る
  • フィールド中の改行は取り除かれる
  • 最終データの後にnullの要素が付く

SKIP_EMPTY | DROP_NEW_LINEを追加

  • 空行は取り除かれる
  • フィールド中の改行は取り除かれる
  • 最終データの後にfalseの要素が付く

READ_AHEAD | SKIP_EMPTYを追加

  • 空行に対応してnullの要素が残る
  • フィールド中の改行は残る
  • 最終データの後には何も付かない

READ_AHEAD | DROP_NEW_LINEを追加

  • 空行に対応してnullの要素が残る
  • フィールド中の改行は取り除かれる
  • 最終データの後にnullの要素が付く

READ_AHEAD | SKIP_EMPTY | DROP_NEW_LINEを追加

  • 空行は取り除かれる
  • フィールド中の改行は取り除かれる
  • 最終データの後には何も付かない

 

 

Laravel – コントローラー

コントローラーの場所

コントローラーは、アプリケーションディレクトリー以下の次のディレクトリーに配置される。

app/Http/Controllers/

一般のコントローラー

概要

  • 一般のコントローラーは複数のアクションを持つ
  • アクションはコントローラーのメソッドとしてpublic宣言される
  • アクションはルーティングで'コントローラー名@アクション名'として呼び出される。

コントローラーの生成

アプリケーションディレクトリー内で以下のコマンドを実行する。

php artisan make:controller コントローラー名

モデル作成時に-c/--controlleroptionを付けると、モデルと同時にコントローラーも作成される。この時のコントローラー名は単数形。

アクションの定義

コントローラークラスのメソッドとしてアクションを定義する。

ルーティング定義

ルーティングファイルで、メソッド・URLとコントローラーを結びつける。

シングルアクションコントローラー

概要

  • シングルアクションコントローラーは、アクションを1つだけ持つ
  • アクション名は__invoke()で定義する
  • ルーティングではコントローラー名のみ指定する

コントローラーの生成

生成は一般のコントローラーと同じ。ただしシングルアクションコントローラーの場合は、コントローラー名の末尾にControllerを付さない慣例あり。たとえばSingleActionなどのようにControllerを付けない。

php artisan make:controller コントローラー名

--invokableオプションを付けると、__invoke()メソッドが準備された状態でコントローラーが生成される。

php artisan make:controller コントローラー名 --invokable

なお、シングルアクションコントローラーを生成する場合は、ルーティングの定義より先に生成しないとエラーが発生する。

アクションの定義

シングルアクションコントローラーのアクション名は__invoke()と決まっている。

ルーティング定義

一般のコントローラー・アクションは'コントローラー名@アクション名'としたのに対して、シングルアクションコントローラーのルーティングではコントローラー名のみ指定する。

 

PHP – php.iniの設定

php.iniの場所

普通は/etc/php.ini

文字コード

もし必要なら変更。

mbstringをインストールしている場合、mbstring.internal_encodingは非推奨となっていて、internal_encodingdefault_charsetが使われるようだ。

internal_encodingの方も、指定していなければdefault_charsetが使われるとのこと。

タイムゾーン

コメントアウトを外し”Asia/Tokyo”を追記。

ブラウザーへのエラー表示

ブラウザーへのエラー表示を有効化のためoff→onに変更。ただし運用時はoffに。

 

Java – InfinityとNaN

Infinity

実数のオーバーフローはInfinity

実数演算で最大値を超えるような演算をすると、結果がInfinityになる。最小値を下回る演算の場合は-InfinityInfinityのリテラルはない。

Infinityに対する数値の演算結果は直感的

Infinityに対して数値を加減乗除しても結果はInfinity。で、数学の∞と同じ。

数値からInfinityを減じると-InfinityInfinityで割ると0.0。lim[x→∞]と考えると直感的。

Infinity同士の演算

Infinity同士の加算・乗算はInfinityInfinity同士の減算・除算はNaN

Infinityと最大値

Infinityは実数の最大値より大きく、これと等しくはない。

Infinity同士の大小比較

InfinityInfinityと等しい。

Infinityの定数定義

Infinitydouble型とfloat型で定義されていて、それらの定数定義も準備されている。

double型とfloat型で、Infinity-Infinityはそれぞれ等しい。

NaN

計算結果が不定→NaN

実数演算でゼロ同士やInfinity同士の除算結果はNaN (Not a Number)になる。NaNのリテラルはない。

NaNを含む演算はNaN

NaNを含む四則演算の結果は全てNaN

NaN != NaN

NaN同士は互いに等しくない。大小関係は特定できない(>でも<でもない)。

NaNの定数定義

NaNdouble型とfloat型で定義されていて、それらの定数定義も準備されている。double型のNaNfloat型のNaNは等しくない(double型同士やfloat型同士と同じように)。

InfinityとNaN

InfinityNaNの演算結果はNaN

InfinityNaNは互いに等しくない。大小関係は特定できない(>でも<でもない)。

 

Rails – 共通ヘルパーの置き場所

概要

複数のコントローラーやビューで共通に利用したいヘルパーの置き場所について。単純なヘルパーの場合、以下の場所が候補になる。

  • app/helpers下のビューに対応した***_helper.rbに記述
  • app/helpers/application_helper.rb内に記述
  • app/controllers/concerns下のモジュールファイルに記述(コントローラー

依存関係を持つような場合はconcernsに置くのがよいようだが、単純なヘルパーの場合はビューとの関連によってapplication_helper.rbに統一するのが簡明かもしれない。

コントローラーに対応したhelper

ヘルパーファイルにヘルパーを記述してapplication_controllerでインクルードすると、コントローラーやビューでこれを使うことができる。

以下はPagesコントローラーの例で、コントローラーとビューの両方でfoo_helperの実行が確認できる。

定義・設定

helpersディレクトリー内にあるコントローラー_helper.rbの中でヘルパーを定義する。

app/helpers/pages_helper.rb

application_controllerでモジュールをインクルード。

app/controllers/application_controller.rb

利用

コントローラーで利用可能。

app/controllers/pages_controller.rb

ビューでも利用可能。

app/views/pages/helper_test.html.erb

application_helper

application_helperもヘルパーファイルの1つで、Railsにより準備される。これを上と同じくapplication_controllerでインクルードして、アプリケーション共通のヘルパーとして使える。

定義・設定

helpersディレクトリー内にあるapplication_helper.rbの中でヘルパーを定義する。

app/helpers/application_helper.rb

application_controllerでモジュールをインクルード。

app/controllers/application_controller.rb

利用

コントローラーで利用可能。

app/controllers/pages_controller.rb

ビューでも利用可能。

app/views/pages/helper_test.html.erb

concerns

app/controllers/concernsにはコントローラー間で共通のモジュール、app/models/concernsはモデル間で共通のモジュールのファイルを配置する。

コントローラーなどでインクルードしてもビューではこれらのモジュールは使えない。

定義・設定

concernsディレクトリー下にモジュールファイルを作成して、その中にヘルパーを書く。

app/controller/concerns/common_module.rb

application_controllerでモジュールをインクルード。

app/controllers/application_controller.rb

利用

コントローラーで利用可能。

app/controllers/pages_controller.rb

しかしビューでは使えない。

 

 

 

Rails – レンダリングされない~form_with

概要

Rails事始めで、フォームから送信した内容を反映させるだけのことが「ページがレンダリングされない」という状態になった話。

結論はfome_withの機能とパラメーターに関するもので、オンラインレッスンの講師の方に教わるまで解決できなかった。

問題の内容

アプリケーション

フォームから受け取った値をインスタンス変数に入れて、それを他のアクションで参照してフォームがあるページを更新するという内容。

躓いてから、できるだけシンプルにしていったのが次のアプリケーションで、フォームのボタンを押すとトップページのテキストの内容を入れ替えるだけのもの。

コントローラー:app/controllers/pages_controller.rb

ビュー:app/views/pages/top.html.erb

ルーティング:config/rotes.rb

症状

以下のページが表示されるが、Submitボタンを押しても画面に変化がない。

よく見ると、inputにルーティングしているのにURLに/inputがついていない。

検証ツールで見ると、inputに対して通信はしていて、書き換えの処理はされているようだ。

コンソールの出力を見ると、POST時の変数の内容は”Hi”に変更されている。

解決

解決策は”form_withのパラメーターにlocal: trueを加える”というものだった。

<%= form_with(url: input_path, local: true) do %>

コントローラー:app/controllers/pages_controller.rb

Submitボタンを押すと表示が変更されるようになった。

理由

form_forでは送信時にページ全体がレンダリングされるが、form_withはデフォルトではajaxによる送信となっていて、そのままではページがレンダリングされない。

パラメーターにlocal: trueを指定するとHTMLとしてのフォーム送信として扱われ、ページがレンダリングされる。

form_tag/form_withがdeprecatedだというところだけを読んで気軽に使ったのが敗因。

 

Vagrant – MySQLのインストール – AmazonLinux2

概要

Vagrant + VirtualBoxのamazonlinux-2にMySQLをインストールした記録。

  • MySQLをローカルインストールする際、展開されたすべてのファイルをインストールする必要がある
  • Amazon Linux 2では標準でMariaDBがインストールされているのでアンインストール

インストール

概要

CentOS7へのインストールと同じ手順で完了した。ただしAmazon Linux 2にデフォルトでインストールされているMariaDBをアンインストール。

MariaDBのアンインストール

wgetの確認

Boxにwgetがインストールされていることを確認。

ダウンロード

ブラウザーで以下のページをたどる。

アーカイブページで以下を選択。

  • Product Version
    • 5.5.62
  • Operating Sysrem
    • Red Hat Enterprise Linux / Oracle Linux
  • OS Version
    • Red Hat Enterprise Linux 7 / Oracle Linux 7 (x86, 64-bit)

一覧の中のRPM Bundle、Downloadボタンを右クリックしてリンクのアドレスをコピー。

コンソールからwgetに上でコピーしたURLを適用してダウンロード。tarファイルがダウンロードされる。

ダウンロードされたtarファイルを確認し、展開。

展開されたファイルのインストール

1つずつsudo yum…でインストールしても、1行にまとめてインストールしても。

全ての展開ファイルのインストールが必要

当初、server、client、embeddedのみをインストールしたところ、不具合が出た。

  • Railsインストール後にプロジェクト生成でエラー
  • MySQLの文字コードセットがdatabaseとserverでlatin1
  • /etc/my.cnfが存在しない

後から残りのファイルをインストールしたところ、上の不具合は全て解消。ただしtestまで必要かどうかは確認していない。

サーバー稼働

サーバーの起動

オリジナルの環境ではservice mysqld startでサーバーを起動していたが、仮想環境ではsystemctlを使う。

ログイン

このバージョンのMySQLは、rootの初期パスワードは設定されていなかった。

文字コードセットの確認

MySQLコンソールからshow variablesで文字コードセットを確認。

 

JS/ES – DOM – textContent, innerText, innerHTML

概要

ブラウザーによる対応の有無もあるようだが、DOMの要素のテキストを扱う3つのプロパティー、textContent, innerText, innerHTMLの機能を確認する。

コード内容と結果

確認に使ったコードは以下の通りで、予め空のa要素を準備し、これに対して3つのプロパティーによってテキストを設定している。

テキストの種類は、プレーンテキスト、エスケープコード含み、HTMLタグ含みの3種類。

これに対して3つのプロパティーの挙動を確認しているので、計9個のリンクの結果を確認する。

HTML

結果

プレーンテキストに対しては、3つのプロパティーとも同じ結果になる。

エスケープコードを含むテキストについては、innerTextはエスケープを機能通りに表示、textContentとinnerHTMLはエスケープの機能は再現しないが、半角空白の文字として表現。

タグに関しては、innerHTMLは反映、他の2つはそのままプレーンテキストとして表示される。つまり、innerHTMLは<や>などの文字がそのまま送られ、innerTextとtextContentでは&lt;や&gt;などの特殊記号に変換されて送られる。

まとめ

textContent innerText innerHTML
プレーンテキスト テキスト表示 テキスト表示 テキスト表示
ESC含みテキスト テキスト表示(ESCは半角SP) ESC機能を反映 テキスト表示(ESCは半角SP)
タグ含みテキスト プレーンテキスト表示 プレーンテキスト表示 タグ機能を反映

Ruby – chomp/chomp!~末尾の改行文字の削除

chompは末尾の改行文字を削除する。ただし"\n\r"の場合は"\n"が削除されずに残る。

"\n\r"を削除したいときは引数に"\n\r"を指定するか、chompを2回実行する(chompは改行文字列だけを削除する)。

末尾以外にある改行文字は削除されない。

chopは非破壊的であり、元の文字列は変更されない。

chop!にすると破壊的メソッドになり、戻り値も変更後の文字列。