A note of a person who is learning programming, SakaTaQ

ロック好きのプログラミング学習

通信、ネットワークの学習まとめ

情報処理においてはよく聞く言葉だけど、あんまり意味がよくわかってない言葉がある。
今回はそれについてザックリとまとめてみました。

サーバー

サービスを提供するコンピュータ、そのコンピュータにある様々な処理、機能。
処理をする為だけに特化したパソコンなどを指す。
自身のパソコンでもサーバー処理自体は行える。

必要な理由

  • バックアップとしてデータを保存しておけば、自身のPCが壊れてもデータを復旧できる。
  • 外部クライアントと接続する機能をサーバーに任せておくことで、自身のPCの負担を減らすことができる。
  • サーバーと開発するためのPCの役割を分けることによって開発に集中できる。

役割

以下のような色々な役割がある。

  • 様々なデータを保存、管理する → データベースサーバー
  • PC同士の通信を行う → WEBサーバー
  • SSHコマンドを受付ける → SSHサーバー
  • メールの送受信を行う → メールサーバー
  • ドメインIPアドレスの組み合わせの管理 → DNSサーバー

WEBサーバー

スマホやPCからのリクエストに対して、リクエストにあったレスポンスを返す仕組みを持ったハード(コンピュータなど)やソフトウェアを指す。
以下のような動作を1秒間に数千回行っている。

  1. 80ポートでHTTPリクエスト受付ける
  2. リクエストに応じた処理や、要求されたファイルを返す
  3. リクエストしたコンピュータに返送(レスポンス)する

IPアドレス

コンピュータやサーバーに設定された住所のようなもの。「123.456.789.000」みたいな形で表現され、全部で42億パターン存在する。
現在では世界の総人口がこの数を超えているため、16進数で表現でき、ほぼ無限に使用できるIPv6というバージョンに移行されている所。
また、これまでのIPv4では個数が限られていたため、利用者が好きに変えることができなかった。その為、ISP(インターネット•サービス•プロバイダ )から自動的に付与されていた。
接続をしていない場合は自動で変動してしまい、IPアドレスを利用する為には毎回ISPから利用許可を貰う必要であった為、企業や学校などでの利用においてコンピュータの数が変動する際に不便であった。
これを解決する為にIPアドレスとプライベートIPアドレスという仕組みが生まれた。

グローバルIPアドレス

インターネット接続する際に利用するアドレス。接続機器に割り振られている番号。家の住所や電話番号のイメージ。
WAN(Wide Area Network)とも呼ばれる。

プライベートIPアドレス

ISPから割り振られたグローバルIPアドレスからさらに細分化させたようなIPアドレス(ネストするようなイメージ)。
グローバルIPアドレスは住所の建物名までだとしたら、プライベートIPアドレスは○号室のイメージ。
LAN(Local Area Network)とも呼ばれ、規模によって3つに分けられる。

  • クラスA(大規模ネットワーク): 10.0.0.0 〜 10.255.255.255
  • クラスB(中規模ネットワーク): 172.16.0.0 〜 172.31.255.255
  • クラスC(小規模ネットワーク): 192.168.0.0 〜 192.168.255.255

ルーターはクラスCを使うのでプライベートIPアドレスは65535通り。
ルーターグローバルIPアドレスの併用では65535 x 42億通りのプライベートIPアドレスが存在できることになる。

ルーター

インターネットと家庭や学校などにある複数のPCを接続する際に必要になる機器。
ルーターを通した時点でグローバルIPからプライベートに切り替わるようになっている。
ルーターは必要に応じてプライベートアドレスを増減させることで接続できる人を固定化させないような仕組みがある。

DNS

Domein Name Systemの略。ドメインIPアドレスを文字列に変換したもの。IPアドレスのような数列を覚えるのが大変な為生み出された。
IPアドレスよりも簡単に取得でき、個人で購入することができる。
ドメインはアドレスバーにある . (ドット)の前後の文字列。 . の後にあるものをトップレベルドメインといい、ドメインを取得するにはトップレベルドメインがなければ取得できない。
. の前にあるものをセカンドレベルドメインという。特に決まりがなくどんな名前にするかは早い者勝ちで、同じ名前を使用することはできない。

DNSサーバー

IPアドレスドメインのそれぞれの組み合わせを管理しているサーバー。
DNSサーバーは様々な場所に存在し、身近なところではルーターの中に存在している場合もある。
IPアドレスを配布しているISP内にもある。

IPアドレスの調べ方

digコマンド

Domein Information Groperの略。ドメインを管理しているDNSサーバーに問い合わせて、ドメインからIPアドレスを取得することができる。

% dig xxxxx.xxxxxx.com

https://とかはいらないので注意。 ANSWER SECTIONの欄に表示されているのがドメインから取得できたIPアドレスとなる。
ネットワークの状況によってはエラーが出ることがある。エラー内容に従ってコマンドを実行する必要がある。+noednsというオプションで解決することがある。

ポート

複数のサーバ同士をつなげる役割を持つ。
それぞれのサーバーはサーバーごとに番号として管理されていて、リクエストに応じてそれぞれの番号(=サーバー)につなぐ橋渡しをする役割を持っている。
ポートの割り振り番号としては0から65535まで使うことができるが、0から1023まではよく使われるもので予約されているので自由に使うことはできない。

必要な理由

一般的なサーバーは1つのIPアドレスしか持ってないことが多いので、このIPアドレスをWEBで使用してしまうと他のサーバーとして動作することができなくなってしまう。
WEBサーバーは80、SSHサーバーは22、メールサーバーは3306などと既に決まっており、利用しようとするとエラーが出る。
Railsでサーバーを起動する時は3000で起動することが多い(寧ろ% rails sのデフォルトは3000)。
既に3000ポートが使用されている場合や、複数のサーバーを起動したい場合は

% rails s -p 3001

のように実行することで別のポートでサーバーを起動できる。
コンピュータが通信する場合は「どのIPアドレス」の「どのポート」に接続するか、というようにセットで考える。

HTTP

WEBページやページ内で必要なCSS, JavaScript、画像などのファイルをWEBサーバにリクエストするためのフォーマット。
http://〜や、https://〜で始まるURL/URIと言う形式で送られる。
ブラウザにURLを入力したり、リンクをクリックした際に、自動的にブラウザがHTTPフォーマット従ったリクエストを作成して、サーバに送信している。
https://はhttpと違ってデータを暗号化して送信する機能がついた通信プロトコル
個人情報を入力したりパスワードを入力するホームページでは、情報漏洩を防ぐために暗号化技術を使用するhttpsが使用される。

URL、URI

URL = Uniform Resource Locaterの略。
インターネット上の住所。ドメイン以外も含めた全てを指す。
同じような仕組みにURN(Uniform Resource Name)と言うものがある。

URI = Uniform Resource Identifierの略。
インターネット上の住所の識別をする書き方の総称。URLよりもこちらの方が広い概念。
https:という識別子はURLとして定められているのではなく、URIで定められている、スキームと呼ばれている。
httpsというプロトコルを使用したスキーム、みたいな言い方になるのかね。

分類というか関係性で言うと、URIが箱ならURLが道具箱、URNがゴミ箱みたいな。そんな感じ。

telnetコマンド

telnetコマンドを使って離れたところにあるホスト(サーバー、ネットワーク機器)に、手元の端末から遠隔操作するために接続することができる。
テキストベースの通信では簡単なものであればncというコマンドの方が簡単に実行できる。
telnetは遠隔ログインに特化しているが、セキュリティ上の理由でsshなどの大体プロトコルを使う場合が多い。
Mac OSのヴァージョンによってはtelnetをインストールする必要がある。

% brew install telnet

まずはdigコマンドでIPアドレスを調べる

% dig xxxa-xxxb.com +noedns

IPアドレスが表示されたら、それを利用してtelnetコマンドを入力、Webページを開くためのポートは80番を使用する。

% telnet 111.222.333.44 80

telnet <IPアドレス> 80のような形で入力する。
コンソール上でトップページが開けたら、GET / HTTP/1.0 と入力し、returnキーを2回押す。 実行することでターミナル上にトップページのHTMLが返ってくる。
<! DOCTYPE html>より上の部分がレスポンスヘッド(headタグ)の部分で、それ以降がメッセージボディ(bodyタグ)の部分になる。

  • HTTP/1.1 200 OK
    レスポンスが成功した際に表示される。200とか300とか400とか500とか種類がある。
    rails sした時のターミナルでの表示結果にもこの数字は表示されるし、JSのajax通信の際にもresponseで取得できる数字があるけど、これと一緒。
  • Content type
    HTMLファイルに使用している文字コードを示している。文字化けなどを誤動作を防ぐためにある。metaタグでよく見る。
  • X-Content-Type-Options:〜
    XSS(クロスサイトスクリプティング = スクリプトの埋め込みによる情報を盗む行為)などによってcookieの情報が盗まれないようにしている。
  • Vary:〜
    キャッシュ(メモリなどの記憶装置に複製されたデータ)を残すためのもの。キャッシュがあると次に同じページに接続する時に、キャッシュがある分は読み込まなくてもよくなるので、読み込み速度が上がる。

pingコマンド

通信したいホストに対して通信できるのかを確認したり、応答時間を調査できるコマンド。
第1引数にIPアドレスもしくはホスト名を書く。

% ping www.abcdefg.co.jp

表示された結果の中に time=6.78 ms などのように表示されているのが通信するまでにかかった時間(単位はミリ秒)。5ミリ秒以内であればかなり近いネットワークに相手のコンピュータがあることが分かるらしい。
なお、確認が済んだ後は Ctrl + Cで終了をする必要がある。


今回はここまで。まだまだ沢山あるけれどもまた学んだことをまとめられたらザァッと書き出していこうと思います。

したらな❗️ 👋

git rebase -i を使ってみた

色々と作っている際にtypoの修正だったりで細かいコミットが増えた時に、コミットログをまとめてしまっても問題ない場合に使えないかな?
と、思ってちと使ってみました。

状況より

f:id:saka20taku43:20200509132237p:plain

実務でチーム開発しているわけでもないですが、いずれはgitを使わない時が来なくなるかもなので、何事も練習精神ってことで。

現在、特に大きな変更点がないコミットばかりが多数残ってしまってるので、これをまとめてしまいたいなって時に git rebase -i が使えるよってことですね。
rebase 自体がブランチの歴史の書き換えとかを行うコマンド。
-i は --intaractiveの略で、対話的という意味のオプション。
対話的に現在のブランチのコミットログを構築し直すことができるという機能 、やはり言葉だけでは僕は理解できません😅

行ったこと

添付画像にある通りですが、まずは現状のコミットのログの確認

% git log

ターミナル上にコミットのログが表示される。最新のものが一番上に来るようになっている。
今回は、masterブランチのみしか存在しない。別のブランチで作業を行っていて、そのログを確認、まとめたい場合は% git checkout ブランチ名でブランチを切り替えてからlogやrebaseを行わないと別のブランチのログが出てきてしまうので注意する。
(とりあえず、masterでやる意味あるのか?という疑問はさておき) まとめる為のコマンドとしては

% git rebase -i HEAD~n

n には最新のコミットである[ HEAD ]から数えて何番目まで構築し直させるか、で数字を入力する。
今回はコミットを開始した時のものと、それ以降の「テスト」「ファイルの修正、準備」「READMEの修正(最新)」の4つのコミットをまとめたもの、2つで分けたいとしている。 全部で5つコミットがある内、最新から4つまでをまとめたい為、n=4 となる。

% git rebase -i HEAD~4

f:id:saka20taku43:20200509135455p:plain コマンドを打つとvimが起動する。
コミットは上の4行で、コマンド コミット番号 コミットメッセージの順で書かれている。
コマンドは下側に一覧があり、そこから使用するものを選んでいる、という形。
pickコミットを使用
rewordコミットを使用するが、コミットメッセージを編集
editコミットを使用するが、修正のために停止する
squashコミットは使うが、以前のものにマージする
fixupsquashと似ているが、このコミットのログメッセージは破棄する
execシェルを使用してコマンド(行の残りの部分)を実行する
breakここで停止(git rebase --continue を使用して後でrebaseを続行)
dropコミットを削除
label現在のHEADに名前をつける
resetHEADをラベルにリセットする
merge元のマージコミットメッセージ(または元のマージコミットが指定されていない場合は1行)を使用して、マージコミットを作成します。コミットメッセージを元に戻すには、-c <commit>を使用します。

今回はコミットを1つにまとめmメッセージを変更したいので1行目のみを reword にし、それ以外はマージする(削除ではないので注意)。 iを押して挿入モードにして編集したら、:wqで保存しながら終了する。

f:id:saka20taku43:20200509144536p:plain reword を選択したので、1行目のコミットメッセージの編集をinsertモードで行い、:wq。

次に表示されているのは「これは4つのコミットの組み合わせです。最初のコミットメッセージ:〜」の形になっている。
f:id:saka20taku43:20200509145441p:plain 今回は4つのコミットをまとめてコミットログを書き換えたいので f:id:saka20taku43:20200509145527p:plain と書き換えて :wq

rebaseに成功した。念のため% git logでコミットログを確認。 f:id:saka20taku43:20200509150152p:plain

参考にさせていただいた記事: git rebase -i はやっぱりイケてる件【git】【rebase 】【iオプション】

今回ザッと書き出しましたが、他にもコマンドがあるので、使う機会があったら試してみたいですね。
調べて、試して、残す、を繰り返すのみ❗️

したらな❗️ 👋

Node.jsについて学習した際の備忘録

npmの名前にも使われているnode。
これについてもザッと学習したことをまとめる。

Node.js

JavaScriptは本来クライアント側で動く言語だけど、Node.jsはサーバーサイド側で動くプラットフォーム。
nodebrewというバージョン管理ツールで指定した Node.jsをインストールできる。 インストール方法については別記事でまとめる。

Node.jsの動かし方はrubyファイルの動作のさせ方と同じイメージで

% node

これでコンソールには>と表示され、入力待機状態になる。これをREPLという。

REPL(Read-Eval-Print-Loop)

入力したコードをその場で実行して、結果を表示するツール。
RubyRails学習者としてのイメージは、rails cで使えるirbや、Chromeブラウザ上で使えるConsoleタブ。
終了する場合は Ctrl + C を2回入力する。1回目は(^C again to quit)と出てくるので従えばOK。
 
 
 
 
ファイルに書いたプログラムを実行することもできる。

% node ファイル名
% node ファイル名 引数

例)
% node app.js
% node app.js 10

ファイル名 app.js の中身は以下のような感じとする。

'use strict';
const number = process.argv[2] || 0;
let sum = 0;
for (let i = 1; i <= number; i++){
    sum = sum + i;    
}
console.log(sum);

引数の数字より高い数字になるまで繰り返しで数を足していく処理をする。
10が引数であれば1 + 2 + 3 + ... + 10みたいな感じ。

Node.jsではモジュールという仕組みを使っている為、HTMLの時に使っていたような

(function () {
'use strict';
// 実行したい処理
})()

無名関数で囲う必要がないので、書き方が少し違う。

'use strict'

strict モードでは、従来は受け入れていた一部のミスをエラーに変更します。JavaScript は未熟な開発者にも易しいように設計され、またエラーとすべき操作の一部をエラーとして扱いません。これにより当面の問題を解決したことがありますが、後により大きな問題を引き起こしたこともあります。strict モードではこれらのミスをエラーとして扱うことで、開発者は気づいて修正するようになります。

こちらのサイトより一部抜粋
ざっくりいうと書き間違えがないか厳しく見てエラーが出ているところを教えてくれるモード。
キチンとした書き方ができない間はこれを使うと中々実行できなくなるけど...

process.argv

Node.jsがデフォルトで提供してくれる、コマンドラインの引数が入った配列。

  • [0]にはnodeコマンドのファイルのパスが入る
  • [1]には実行しているプログラムのパスが入る
  • [2]は引数が入る

process.argv[2] || 0; の後ろにある条件付き論理和は左側からTruthy(真)であるかを判定する。
左側の値がFalsy(偽 = null, undefined, 0の形)であれば右側の値を結果として使うという特性を持つ。
コマンドラインで引数があればその値をnumberに代入、なければ0を代入する。

プログラムの実行速度を測定するのにtimeコマンドを利用できる。

% time node app.js

実際にかかった全体の時間と、実行ユーザーとしてかかった時間、システムが別の処理に使った時間が出てくる。  
 

...Nodeは少し思い出があって、Macのアプデしたらnodebrewが消失する事件にしっかり巻き込まれて、Rails起動しなくて焦った一人。 JavaScriptランタイムがないって言われて、gem 'mini_racer'入れろみたいなのが出てきて
「何故入れてなかったものを入れないといけないのか意味不明」
ってなり、サーバーサイドでJS使えないみたいな感じかな?って勘みたいなものでhomebrewからバージョン調べてみたら気付けた。

この時に参考にした記事
なぜ、Ruby on Railsの動作にNode.jsが必要なのか

あれ以来、即アプデが怖くてできない...
もっと実力つけて何でも対応できるようにならなきゃ...😅  
 
 

stream

Node.jsでは、入出力が発生する処理をほとんどこの形で扱う。
非同期で情報を取り扱う為の概念で、情報自体ではなく情報の流れに注目。

factorial()

階乗を計算する関数。引数に渡した数だけ順番に掛ける。再帰処理を同時にやるケースが多いみたいです。
参考にさせていただいた記事

equal()

イコールのこと。比較演算子参考にさせていただいた記事

resume()

ストリームに情報を流し始める処理。
AudioContext.resume()MediaRecorder.resume()に共通している記述は一時停止していた記録や流れの再開とある。

map関数

REPL> [1, 2, 3].map((i) => { return i * 2; })
=> [2, 4, 6]
Arrayの要素それぞれを、与えられた関数を適用した内容に変換する。
「与えられた整数を2倍にする」という関数を配列の各要素に適用して新しい配列を得ている。

Map

var map = new Map();で空のMapオブジェクトを生成できる。 これにより生成されるオブジェクトはキーと値の組み合わせの形で保持できる、とあるのでrubyでいうハッシュに近い感じだと思ってる...けど、連想配列っていう言葉で表現されてますね。
参考にさせていただいた記事

Math

数学的な定数と関数を持つプロパティとメソッドを持つ組み込みオブジェクト。関数オブジェクトではない。やたらと色んなところで出てくる。
参考にさせていただいた記事

Math.floor()

引数として与えた数以下の最大の整数で返す。静的メソッド。
Math.floor( 45.44);=> 45
Math.floor(-45.05);=> -46
参考にさせていただいた記事

Math.random()

そのまま使用すれば0以上1未満の浮動小数点の擬似乱数を返す(0.6235435みたいな感じ)。
Math.floorと合わせて使うことでいろいろな範囲の乱数として実装できる。

const names = ['太郎', '次郎', '三郎', '四郎'];
const name = names[Math.floor(Math.random() * names.length)];
console.log(name);
=>実行するたびに結果が変わる。

2行目で一番最初に見る部分として、今回のケースだとMath.random() * 4になる。 Math.floor()で囲っているので小数点を省いた整数に切り捨てされたものが、[ ]内の添字になり、names[ ]の形になったものをnameに代入させている、と。
参考にさせていただいた記事

Templete Literal

`(バッククォーテーション)で囲まれている文字列に${プログラム内の値、変数など}という形式の文字列を含めることで変数などを埋め込むことができるテンプレートリテラルという機能になる。

for-of構文

for (let culc of map) { // 繰り返したい処理内容 }
MapオブジェクトやArrayなどの中身をofの前の変数(ここではculc)に代入してforと同じループ処理する書き方。 配列に含まれる要素を使いだけで添字は不要な場合に有用。

二つのお店の看板メニューで各々得られるカロリーの摂取効率の計算を行うとする。

console.log(map);
=>
Map {
  '好き家' => { signboard: 350, calorie: 400, perform: null}, 
  '待つ屋' => { signboard: 300, calorie: 320, perform: null}
}
for (let culc of map) {
  const value = culc[1];
  value.perform = value.calorie / value.signboard;
}
console.log(map);

Mapオブジェクトにfor-ofを使用した場合には、キー、バリューと要素が二つある配列が変数に代入される。culc[0]でキーである店の名前(好き野など)、[1]であれば{}の中にあるオブジェクトを取得する。
取得したvalueに対してメソッドを使用する形でキーを入力する(.calorieなど)と値を取り出すことができる。
繰り返し処理後の実行結果は

Map {
  '好き家' => { signboard: 350, calorie: 400, perform: 1.14285714}, 
  '待つ屋' => { signboard: 300, calorie: 320, perform: 1.06666666}
}

これで値段あたりの摂取カロリー量の計算を出来たことがわかった。

const assert = require('モジュール名')

モジュールをオブジェクトとして読み込む記述方法。

assert

Node.jsが持っているアサーションという簡易テストの為のモジュール。
const assert = require('assert')
参考にさせていただいた記事

fs

FileSystemの略で、ファイルを扱う為のモジュール。
const assert = require('fs')

readline

ファイルを1行ずつ読み込む為のモジュール。
const assert = require('readline')

nodegrind

処理に時間がかかっている様子、メモリの使用量を調べる方法にプロファイルがある。
これらを見る為のプロファイルツール。
nodegrind -o app.cpuprofile app.jsを実行することで「app.cpuprofile」ファイルにプロファイルの様子が出力される。
Google Chromeデベロッパーツール[Profile]タブで見ることができる。

指数オーダー

O記法でO(a^n)と記述。aは定数で、指数オーダーの計算はコンピュータは難しい。
回を重ねると倍々に計算回数が増えるような処理の増え方をいう。

線形オーダー

O記法でO(n)で、nに対してn倍処理時間がかかるオーダー。
基本的にはnに対してn倍の時間をかければ解くことができるので処理が圧倒的に速くなる。


JavaScriptは派生も多く学習がとても大変でした。これ、使いこなせる日が来るのだろうか...
とりあえず今は学び続けるしかない。

したらな❗️ 👋

npmについて備忘録

経緯として、railsのbundleとかもそうだけど色々と触っていてよく分からんことがあったので。
今回はJavaScript触ってて出てきたことをまとめてみる。
まぁ、ぶっちゃけ分からんことだらけなので...

npm

npmとはNode.jsのパッケージを管理するもの。Node Package Managerの略。

  • インストールされているライブラリのパッケージの記録
  • 新しいパッケージのインストールや削除

こんな感じの便利機能がまとめられたもの。
パッケージ間に依存関係がある場合には、インストールしたパッケージに必要となるパッケージまで自動的にインストールしてくれる。

% npm

と打てばターミナルに使い方が表示される。詳細な使い方については

% npm -l

と打つ。
また、npmでインストールされたものの詳細を確認するには

% npm -g ls

と打つ。これでインストールされているパッケージの依存関係を表すツリーが表示される。
-g というのはグローバルにインストールされたものを指す。
npmにはグローバルインストールとローカルインストールの2つのインストール方法が用意されている。

グローバルインストール

Node.jsの実行環境自体にパッケージをインストール

% npm install -g パッケージ名

例
% npm install -g nodegrind

のように -g をつける。

ローカルインストール

現在のディレクトリでインストール。ローカルインストールされた時に、node_modulesディレクトリがパッケージとなってインストールされるディレクトリ。
CUIで対象となるディレクトリ上に移動して

% npm install パッケージ名

例)
% npm install request

などのように入力すると
request@2.87.0 node_modules/request
インストールのメッセージが表示される。

間違ってインストールしてしまったものがあった場合はアンインストール

npm uninstall パッケージ名

例)
npm uninstall sum

npmのパッケージは自作することも可能。initというコマンドを使う

cd greet
npm init

実行するとチュートリアルが起動し、 package.json というnpm のパッケージ情報を書き込む流れになる。

  • name: (greet)でパッケージ名。このままでよければreturnキーを押し、greetとする。
  • version: (1.0.0)でバージョンを決める。そのままでよければ同上。
  • description:で説明文を付けられる。入力は任意。
  • enter point: (hello.js)ライブラリを読み込んだ際に最初に実行するJavaScriptファイル(エントリポイントという)を設定する。
  • test command:テストコマンドの設定。なしでよいならそのままreturnキーを押す。
    node test.jsなどと入力しておき、動作確認のための test.js ファイルを作成してテスト用のコードを書くことで、実際のslack環境でなくてもコンソール上でテストできる。
    この時、実際にテストをする際の呼び出しは% node testのように記述する。
    Railsでいうところのrspec-railsやcapybaraみたいなイメージ。
  • keywords:登録時の検索キーワードの設定。なしなら同上。
  • author:ライブラリの著者の設定。なしなら同上。
  • license: (ISC)ライブラリのライセンス設定をする。そのまま決定するとISCライセンスとなる。ISCライセンスは使用、コピー、改変、配布する許可を与えるライセンス。UNLICENSED、MITなど種類がいくつかあるみたい。

必要事項を入力し終わったらIs this ok ? (yes)と聞かれるのでreturnを押すと今回であればgreedディレクトリの中にpackage.jsonファイルが生成される。

このファイル自体に直接書き込むことも可能で、一番下に"private": trueなどのように追加すれば、公開も防ぐように設定することができる。

npm initする時に呼び出されるファイル自体をカスタマイズすることもできるみたい。
参考にさせていただいた記事 npm initでauthorやlicenseなどの初期値を指定する

greet/hello.jsを編集する。

自作したnpmはローカルのフォルダを指定してインストールすることも可能。

ディレクトリ構造例)
projects ┬ conversation
      ┗ greet

npm install ../greet


自分のためのパッケージ作れるのって後々便利になりそう。

したらな❗️ 👋

GitHub Pagesで静的サイトを公開する

CUIGUI混ぜ混ぜで。
GitHub Desktopを使用しています。

まずはGitHubのトップ画面で新規のリモートリポジトリの作成

f:id:saka20taku43:20200502162323p:plainf:id:saka20taku43:20200502162328p:plain

緑のNewボタン、左のメニューの一番上、どっちでも同じ画面に移動します。

f:id:saka20taku43:20200502162812p:plain

  • Repository nameは名前。ローカルでディレクトリ名のイメージ。分かり易ければなんでもよい。
  • Descriptionは説明文。必須ではなく任意。READMEに書けば良いので必要はないっちゃない。
  • 次のラジオボタンの部分は、公開するならPublic。とっても秘密裏に開発を行う場合はPrivateにする。
  • その下のチェックボックスリポジトリの説明文(README.md)を作成するかどうかのボックス。リポジトリには初期設定が必要でREADMEを追加しておくとその設定を省ける。
  • Add .gitignore、Add a licenseについては最下記にて。今回はとりあえずで公開テストをするために作成したので必要がないので無記。

作成するとこんなページに行く。 f:id:saka20taku43:20200502173528p:plain

1段落目にアドレスがあるので右にあるボードボタン押してコピーしたら、ターミナルで

% cd ~/projects
% git clone [アドレスのペースト]
% cd [Repository nameで記述した名前]

ローカルリポジトリを作成し、cdで移動。

2段落目の部分はREADMEあたりで言っていた初期設定とか説明ですね。最初はgit initしてgit管理するように設定とかいうアレ。
READMEは現状必要ないので代わりと言ってはなんですが、Webページ用に本文テキストを入力したindex.htmlを作成

$ echo "Welcome to GitHub Pages !!" > index.html

次に、GitHub Desktopの操作。

f:id:saka20taku43:20200502175853p:plain
ターミナルでgit cloneしましたが、clone Reposirotyでアドレス貼ってもOKですね。あんまり使った事ないけどw

※ 5/8更新
cloneしたいアドレスを上側にコピペ、下側はcloneしたリポジトリを入れる場所を指定。 f:id:saka20taku43:20200508190446p:plain

今回はAdd Existing Repositoryで既にcloneしてあるリポジトリをchooseで選択し、ローカルリポジトリとして設定しました。

f:id:saka20taku43:20200502180914p:plain
変更内容がステージングされているのが確認できたら

f:id:saka20taku43:20200502180618p:plain
上側の小さい入力フォームにコミットメッセージのタイトルを記述。こちらはないとどういった変更をしたのかが分からなくなるので必要です。
具体的に詳細を書く場合は下のDescriptionに記述。
その後は青いボタンを押してcommit。 commit後はFetch originのタブの辺りにpublish branchって出てきますが、これを押す事でリモート側にpushできます。最初はこの表記で以降はpush originって表示されます。少し下にも同じ青いボタンが出てきますが、どっち押しても同じです。
CUIは視覚的に分かりづらいですが、ターミナルで

% git add .
% git commit -m '[コミットメッセージ]'
% git push origin master

と入力して実行すれば同じことが出来るのでこっちのが早いっすね。

pushしたらGitHubのリモートリポジトリにアクセスし、Settingタブをクリック。

f:id:saka20taku43:20200502182918p:plainf:id:saka20taku43:20200502182945p:plain

下の方に行くとGirHub Pages欄があるのでSourceをmaster branchにすると

f:id:saka20taku43:20200502183329p:plain

切り替わった後にサイトを公開する準備が整ったと出てくる
Your site is ready to be published at https://seramay.github.io/test-pages/

クリックすると

f:id:saka20taku43:20200502183759p:plain

これで公開できるようになった、と。感動した!!
※ 公開数時間後にcss、js適用テスト行ったため、現状は内容が違います。

気をつけなくてはいけないのが、これまで僕が学んできたRailsで作成したサーバーを扱うような動的サイトは違う形(AWSやHeroku)で公開する必要があるってこと。

今回参考にさせていただいた記事
GitHub Pagesでウェブサイト公開
GitHub Pagesを使ってサクッとWebページを公開する


.gitignoreファイル

Add .gitignoreは.gitignoreファイルをデフォルトで作成するかというもの。
で、.gitignoreって何なのかですが、git の管理対象から外すファイル名やディレクトリ名を記述する際に使用する。
僕は脳味噌風船野郎なのでこれだけでは「だから何?」って言う感じなのですが、管理対象から外しておく(記述しておく)ことで、例えばアプリなどを制作してローカル側で変更があった内容を全てcommitしてリモートにpushする際に、.gitignoreに記述されているファイル等はcommitされなくなります。
なんでそんなことする必要があるかと言うと、リモートリポジトリ側でPublicにしている場合、pushされたファイル名にアクセスした全てのユーザーが見ることができるわけなので、

  • 公開したくない個人情報やパスワードなどの設定ファイル(master.keyや.env)
  • 管理する必要がない投稿された画像ファイルを格納するディレクトリなど

を記述しておき、gitの管理対象から外しておく必要があるというわけです。う〜ん、難しい!
注意点としては一度pushしてしまったファイルなどは.gitignoreに記述しても、管理対象から外すことはできず、変更された内容はそのままpushされ更新してしまう事。
最初にpushする前に確認して.gitignoreに書いておかないといけないってことですな。

そういった場合の具体例を備忘録として残しておく(自分のためですw)

sample-appディレクトリで作業していた内容を一度pushしてしまってから.gitignoreで

config/secrets.yml
.env

の2つのファイルを管理対象から外したいってなった場合、ターミナル側で

% cd ~/projects/sample-app
% git rm --cached config/secrets.yml
% git rm --cached .env

まず、管理対象から外したいファイルがあるアプリケーションのディレクトリにcdで移動。
2行目と3行目のコマンドでファイルを消さずに管理対象から外す。
git rm --cached [ファイル名]の形。

--cachedオプションをつけないとファイルごと消えてしまうので注意が必要。

参考にさせていただいた記事
【Git】git rm --cached [ファイル名]:ファイルを管理対象から除外する

Add a license

リポジトリにライセンスを付与するか、というもの。
オリジナルのフレームワークだったり、ライブラリを作る場合は必要なのかもですが、当然今の僕には不要。

もっと公開しやすくなるように色々学ばないといけないですね。

したらな❗️ 👋

active_hashについて

都道府県などの静的データはactive_hashを利用しましょう

とレビューを頂いたことから調べて実装に至りました。
その際に参考にさせていただいたサイト。

とても分かりやすかったので導入もスムーズに行きました。
Railsにありがちな最新バージョンはよくないことあるかも、みたいな情報も助かりました。
...壊れた時のことをあまり考えてなかったので今回は最新のactive_hashを記述しましたが😅

導入した時のアプリのバージョン

5.2系は5.2.3の方がよかったのかなって思いましたが、この時は何か別のアプリで参考にしたのかな...覚えてない...

gemで用意されてるので、Gemfileに

gem 'active_hash'

上述していたアプリが壊れる可能性のことを考慮するなら、Rails5であれば
gem 'active_hash', '~> 2.3.0'が推奨されているそうです。
Rails5未満、Ruby2.4未満の場合は
gem 'active_hash', '~> 1.5.3'

記入したらターミナルに

% bundle install

入力して実行。

実装したアプリでは、ユーザーの住所 = 出品物の配送場所とは限らない、という想定からrails g model Addressとかはしてなかったような。
そのままPrefecture.rbを手入力で作成する形としました。

class Prefecture < ActiveHash::Base
  self.data = [
      {id: 1, name: '北海道'}, {id: 2, name: '青森県'}, {id: 3, name: '岩手県'},
      {id: 4, name: '宮城県'}, {id: 5, name: '秋田県'}, {id: 6, name: '山形県'},
      {id: 7, name: '福島県'}, {id: 8, name: '茨城県'}, {id: 9, name: '栃木県'},
      {id: 10, name: '群馬県'}, {id: 11, name: '埼玉県'}, {id: 12, name: '千葉県'},
      {id: 13, name: '東京都'}, {id: 14, name: '神奈川県'}, {id: 15, name: '新潟県'},
      {id: 16, name: '富山県'}, {id: 17, name: '石川県'}, {id: 18, name: '福井県'},
      {id: 19, name: '山梨県'}, {id: 20, name: '長野県'}, {id: 21, name: '岐阜県'},
      {id: 22, name: '静岡県'}, {id: 23, name: '愛知県'}, {id: 24, name: '三重県'},
      {id: 25, name: '滋賀県'}, {id: 26, name: '京都府'}, {id: 27, name: '大阪府'},
      {id: 28, name: '兵庫県'}, {id: 29, name: '奈良県'}, {id: 30, name: '和歌山県'},
      {id: 31, name: '鳥取県'}, {id: 32, name: '島根県'}, {id: 33, name: '岡山県'},
      {id: 34, name: '広島県'}, {id: 35, name: '山口県'}, {id: 36, name: '徳島県'},
      {id: 37, name: '香川県'}, {id: 38, name: '愛媛県'}, {id: 39, name: '高知県'},
      {id: 40, name: '福岡県'}, {id: 41, name: '佐賀県'}, {id: 42, name: '長崎県'},
      {id: 43, name: '熊本県'}, {id: 44, name: '大分県'}, {id: 45, name: '宮崎県'},
      {id: 46, name: '鹿児島県'}, {id: 47, name: '沖縄県'}
  ]
end

ActiveHash::Baseを継承したモデルを作成するとActiveRecordのメソッドが使用できるとのこと。 active_hashを使用した時以外でも打ってみたことがありますが、
[1] pry(main) > % Prefecture.methods
のようにすることで使用できるメソッドの一覧をターミナルで確認できます。
今回使用したのは割とよく使われるメソッドですが、

  =  f.collection_select :ship_area, Prefecture.all, :id, :name, prompt:'---'

のような.allだったりを使用してPrefectureモデルをベースにセレクトボックスを生成することができる、ってわけですね。便利!

DB内容を操作するような複雑な処理には適さないそうです。 その場合は、素直にテーブルを用意するか、enumはどうかな...?どちらにしろ、別の適した形で対応するのが望ましそうですね。

別記サイトでも書いていましたが、Addressなどと直接紐づけるなら

class Address < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to_active_hash :prefecture
end

のように、belongs_to_active_hash :[model名]でアソシエーションを組むことができる。
ただしこの時、extend ActiveHash::Associations::ActiveRecordExtensionsしないとprefectureモデルは使えない。
詳細は公式GitHubのrepositoryにありますね。 今のところ利用する為の根本?bundleやgemについてはまだよく理解できいませんが、このように定義されているmoduleからどう言う処理をさせるか書いてるんですね〜。すげーなー。

他に不変的なデータとかって言うのは国名とか生年月日とかでしょうか?
enumもそうですが、単純にモデル作成 = データベース設計&作成、をしなくてもいいのでとてもありがたい機能。

今回はここまで。
したらな❗️ 👋

enumについてとboolean型で少し知ったこと

enum

enumは「列挙型」のこと。int型、boolean型で定義されたカラムを文字列で表現する可読性向上の為の機能で、ActiveRecord :: Enumと言うモジュールにより使用できる。いつものActive〜で定義されていてそれが継承されているので使える的なアレですね。
使う場面としては、クラスにするほどでもなくactive_hashにし辛い(ことなんてあるのか?)というような、変動性は高いけどある程度まとまった群、を用意する場面で、かつ、それが数字だけだと何番が何を指しているか分からんって場合ですね。

実際に使用した例から言うと、例えばサイズとかはS, M, L, LLってあるけど、そういったアプリとかであればSSやXLも増やしたいとか、3L追加した時とかにLL => 2Lに改名したい時とか出てくるハズ。そういうイデア的な範囲感←

  • ビューでロジックを用意すると記述があまりにも多くなってしまうし使い回しにくい
  • コントローラーで複雑なロジックを書くのは規則的によくない

で、モデルに記述することが多いそうです。

class Item < ApplicationRecord
  enum size: [ :S, :M, :L, :LL, :XL], _prefix: true
end
[1] pry(main) > @cloth = Item.new(size: 1)
[2] pry(main) > @cloth.size
=> 'M' 

rails cで確認すると数値ではなく、enumで定義した文字列を返す

[1] pry(main) > Item.sizes
=> {"S"=>0, "M"=>1, "L"=>2, "LL"=>3, "XL"=>4}

[モデル名].[カラム名の複数形]の形でそのカラムに設定した全てのenumを表示させることができる。これはビューのセレクトボックスに使う、と。

= form_with scope: :item, model: @item, local: true do |f|
  = f.select :size, Item.sizes, prompt: '---'

 
また、定義の仕方に関しては以下のように書くこともできるようです。

class Item < ApplicationRecord
  enum size: { "S": 0, "M": 1, "L": 2, "LL": 3, "XL": 4}, _prefix: true
end

enum カラム名: {定義対象の内容のマッピング 名前: 数値}のような形。
実際に使った時の記述とは訳あって少し違いますが、一般的な定義の仕方はこんな感じらしいッス。 数値と組み合わせるだけなら上の書き方で問題ない気もしますが。

_prefix: trueは設定しておくと、他のenumのマップの内容と重複してもエラーが出なくなる。今回は内容的に被り用がないけど念のため記述している。

[1] pry(main) > item.condition_good!
=> # 更新される
[2] pry(main) > item.condition_good?
=> true

こんな感じで呼び出して条件文とかに使用することもできる。

因みに、公式リファレンスでは「一番最初に宣言した値をデフォルト値としてモデルに定義することを推奨」されている。

class CreateItems < ActiveRecord::Migration[5.2]
  def change
    create_table :items do |t|
      #...略
      t.integer :size, defalut: 0
      #...略
  end
end

テーブルやカラム情報を設定するマイグレーションファイルの記述。
上記のようにテーブル作成時はモデル自体がない = enum定義前なので、ここでは名前定義使えないので数値で指定する必要があるので注意。
サイズのデフォルトが"S"ってちょっと...ってなるのはご愛嬌😌
 
主に参考にさせていただいた記事。booleanについても試されてる。
boolean型は公式も含めて参考にできる記載が少ないとのこと。
Enumってどんな子?使えるの?


boolean型カラム

使ったことはないですが、ブーリアンと読むみたいでブール型って呼ばれてる。
真偽、オンオフを保存するのに使う感じ。某ツクールシリーズに影響を受けた世代的にはスイッチのように扱えそうです。
行ったか行ってないか、みたいな条件でnilが返ると大変面倒くさそうなので基本的にはNOT NULL制約であるnull: falseと初期値(default)の設定のdefault: false必須。
表示、用意、設定したからには基本は指定無しや状態不明ではなくてオフってことで。


enum_help

enumを日本語化するgem。Gemfileに

gem 'enum_help'

記入したらターミナルで

% bundle install

 
gem 'rails-i18n'と使用イメージは近い。ハッキリ言ってsizeカラムとして用意してるenumに日本語化が必要かと言われたらNOなのでconditionカラムで書いてみました。定義部分は脳内変換でお願いします
 
config/localsディレクトリにja.ymlファイルを用意して、

ja:
  enums:
    item:
      condition:
        good: "新品同様"
        scratch: "やや傷あり"
        bad: "状態が悪い"
  activerecord:
    attributes:
      item:
        name: 商品名
        price: 価格
        description: 商品の説明
        condition: 商品の状態
        size: 商品のサイズ
        ship_area: 発送元の地域
        ship_day: 発送までの日数
        ship_price: 配送料の負担
        ship_method: 配送の方法
        item_images: 商品の画像
        category: カテゴリー

注意点はインデント。
っていうかenumの定義の時点で日本語で書いとけばそもそも必要ないような...。←

補足事項みたいなのつけてたら長くなったのでactive_hashは別記。

したらな❗️ 👋