君は心理学者なのか?

大学時代に心理学を専攻しなぜかプログラマになった、サイコ(心理学)プログラマかろてんの雑記。

Angularを使って、カートで商品を選択する画面を作ってみた〜親子コンポーネント・サービス間連携をしてみる〜

Angularの復習をしようと思った

今回の開発で、Angularを使った。

基本フロント側は一人で開発をしていたが、

1画面で扱っているコンポーネントの数が600個をこえたり、

画面間で引き継ぐ項目がどんどん増えてきたりで、

だんだん大変なことになってきた。

なぜ大変な事になってきたか

サービス増えすぎ問題

それぞれのコンポーネントで値(以下、モデル)を共有させようとした時に、

サービスをDIして共有させていた。

モデルごとにサービスを作ってしまっていたので、

モデルが増えるたびにサービスが増え、大変なことになってしまった。

サービスの役割2つあるよ問題

ページ間をまたがないデータはコンポーネントに持たせればよいのに、

なぜかサービスにデータを持たせてしまっていた。

よって、

サービスが「データの保持」「データ処理」の2つの役割を持ってしまっていた。

サービスの役割が曖昧になり、追加でいじる時にどこをいじればよいのかわかりにくくなってしまっていた。

作ったのがこれ

f:id:karoten512:20180128205736g:plain

github.com

説明

構成

f:id:karoten512:20180128211839p:plain

最上位にAppComponentをおく。

このコンポーネントが、この画面で扱うすべてのプロパティを保持している。

子供はAppComponentのプロパティを共有している。

子供で起こったイベントは、AppServiceを通じてAppComponentに伝えられる。

商品をクリックした時、どのように画面が変更されるか

クリックしたことをAppServiceに伝える

f:id:karoten512:20180128211859p:plain

AppServiceは、AppComponentが持っているプロパティを操作する

f:id:karoten512:20180128212001p:plain

コンポーネントに、AppComponentのプロパティ変更が伝わる

f:id:karoten512:20180128212033p:plain

コンポーネントは親のプロパティを共有しているので、

そのまま親のプロパティの変更が伝わります。

画面に結果があらわれる

f:id:karoten512:20180128212121p:plain

まとめ

今回、AppComponentに画面上で扱うすべてのプロパティをもたせたので、

シンプルになった。

また、AppServiceを用いたことにより、

子供から親へのイベントバブリングと言った複雑なことをしなくても良くなった。

今後はこういう設計にしていきたいなぁ。

module.exportsとは何か、どうもわからなかったので実験してみた〜Node.jsにて外部moduleをrequireする〜

f:id:karoten512:20180128191834p:plain

いきさつ

今まで何も考えずに

npm install

して、

var module = require('module-name');

して使ってきたが、

Node.jsについて知らなさすぎて、

node_moduleディレクトリ配下に格納されているmoduleをみても、

ぜんぜん読めないことに気づいた。

exports.moduleが分かればだいぶ読めるようになるかな、と思い、

まずはexports.moduleについて理解することにした。

ディレクトリ構造

├── main.js
└── node_modules
    └── weather-module.js

やってること

main.jsからweather-module.jsを読み込む。

// main.js
var weather = require('weather-module');
weather.today();
weather.yesterday();
// weather-module.js
/** weatherオブジェクトの生成 */
var weather = {}; 

weather.today = function() {
  console.log('晴れだよ');
}

weather.yesterday = function() {
  console.log('雨だったよ');
}

module.exports = weather;

わからないこと

module.exports = weather;

の部分で何をやっているのかわからない。

結論

// main.js
require('weather-module');

requireが、

weather-module.jsでmodule.exportsに渡されているオブジェクトを

返してくれるので、それを使用することができる。

実験手順

何を読み込んでいるのか調べる

これを外部ファイル(main.js)から読み込んで使いたい。

// main.js
var weatherModule = require('weather-module');
console.log(weatherModule);

main.jsを実行

$ node main.js
{ today: [Function], yesterday: [Function] }

weatherオブジェクトそのものが渡っているようである。

weatherオブジェクトはmodule.exportsに渡されているのものなので、

require('weather-module');

module.exportsに渡されているオブジェクトを返す、と考えられる。

module.exportsに複数のオブジェクトを渡してみる

/** weatherオブジェクトの生成 */
var weather = {}; 

weather.today = function() {
  console.log('晴れだよ');
}

/** 関数の追加2 */
weather.yesterday = function() {
  console.log('雨だったよ');
}

/** temperatureオブジェクトの生成 */
var temperature = {}; 

temperature.today = function() {
  console.log('25');
}

temperature.yesterday = function() {
  console.log('15');

}

module.exports = { 
  weather: weather,
  temperature: temperature // もう一個渡す
};

main.jsを実行

$ node main.js
{ weather: { today: [Function], yesterday: [Function] },
  temperature: { today: [Function], yesterday: [Function] } }

やはり、

require('weather-module');

module.exportsに渡されているオブジェクトを返すようだ。

まとめ

require('hoge-module');

hoge-module.jsにて、

module.exportsに渡されているオブジェクトを返す。

逆に言えば、

module.exportsに渡していないオブジェクトは使えない。

外部から使用したいオブジェクトは、必ずmodule.exportsに渡すこと。

参考

numb86-tech.hatenablog.com

本番環境にテストデータを入れてしまったときは、deleteではなくtruncateでテーブルからレコードを一掃しよう〜deleteとtruncateの違い〜

いきさつ

社内で使用するシステムの開発が一旦落ち着いたので、

本番環境構築することになった。

といってもすでにテスト環境を構築しているので、

慣れたものである。

種々のインスタンスを立ち上げ、ansible用のユーザを作成し、

playbookの諸々の設定位置を少し書き換ええ、流すだけで良い。

(playbook、つくるのは大変だった)

で、いつものように本番環境にデプロイし終わり

きちんと登録できるか一通りの操作をした。

そこで先輩が一言

「本番環境上に作ってしまったデータは残してはいけないから、

きちんとtruncateしといてね」

僕はハッとした

当たり前だが、その一言に僕はハッとさせられた。

基本的に本番環境はまっさらな状態で、お客さんに使ってもらう。

使ってもらう時、

私たち開発者がテスト用に打ったゴミデータが入っていると、

アカウント管理をしているとはいえ、

万が一そのゴミデータのせいでバグが起こりうる場合もある。

(そもそも本番環境なので、

 テストデータが紛れ込んでいると言うのはおかしい、というのもある)

なので

テストデータは消しておく必要がある。

そのときに注意しておくのがdeleteとtruncateの違いだ。

deleteとtruncateの違い

idがauto_incrementになっていた場合、

deleteは連番情報を保持したまま。

truncateは1から裁判し直す。

という違いがある。

まっさらな状態にする、という意味ではtruncateが適している。

まとめ

本番環境の扱いには気をつけよう。

シェルで文字列を比較したときに、[: =: unary operator expected :というエラーがでる

f:id:karoten512:20180119002642j:plain

いきさつ

空行を検出するスクリプトを書いていた

古池や

蛙飛び込む
水の音

をシェルに読み込ませ、空行があったときに

「空行があるよ」というスクリプトを書いた。

※ 実際の処理を簡略化してます

#!/bin/bash
while read line
do
  if [ $line = '' ]; then
    echo '空行があるよ'
  fi  
done < line.txt

しかしうごかないんだなこれが

test.sh: line 4: [: =: unary operator expected

というエラーがでる。

どこでエラーが置きているかわからないので、

#!/bin/bash
while read line
do
  echo $line # ここで出力する
  if [ $line = '' ]; then
    echo '空行があるよ'
  fi  
done < line.txt

echo で毎行出力してみる。

古池や

test.sh: line 5: [: =: unary operator expected
蛙飛び込む
水の音

どうやら空行を読み込んだ時に起きているエラーのようだ。

調べてみた

fluidx.exblog.jp

変数に格納されている文字列比較において、 文字列の比較は文字列と行う必要があるところを、 文字列と何かわからない型の変数を比較してしまっているので、 このようなエラーが発生するらしい。

空行は「文字列かわからない型」なのか…?

ちょっとそこは釈然としない。

対処

#!/bin/bash
while read line
do
  if [ "$line" = '' ]; then
    echo '空行があるよ'
  fi  
done < line.txt

$lineを""でかこむ。文字列にキャストしている感じなのかな。

結果

空行があるよ

動いた。

シェルは独特。でもサッとかけるから便利。

環境を選ばないしねぇ。

最強のポータビリティ言語である。

1つのファイルを複数のディレクトリにコピーしたい〜UNIXコマンド:xargsとcpについて〜

f:id:karoten512:20180117121818p:plain

1つのファイルを複数のディレクトリにコピーしたい

dir1, dir2, dir3にfileをコピーしてばらまきたい。

結論

echo dir1 dir2 dir3 | xargs -n 1 cp -v file

読み解いてみる

xargs

とは

標準出力をコマンドライン引数に変えるコマンド。

今回の例で言えば、echoによって出力される標準出力を、

コマンドライン引数としてcpに渡している。

-nオプションとは

数字をすこしいじってみた。

$ echo dir1 dir2 dir3 | xargs -n 1
dir1
dir2
dir3
$ echo dir1 dir2 dir3 | xargs -n 2
dir1 dir2
dir3
$ echo dir1 dir2 dir3 | xargs -n 3
dir1 dir2 dir3

なるほど。

引数をいくつづつ渡すかを指定するコマンドなのね。

cpとは

概要

ファイルをコピーするコマンド。

-vオプションとは

オプション有り。

$ cp -v fileA fileB
flieA -> fileB

オプション無し。

$ cp -v fileA fileB

何も言わねえ。

まとめ

xargs、

コマンドライン引数しかうけとらないコマンドに、

標準出力をわたしたい時に活躍するみたい。

面白いな。

unixコマンドは1つ1つの機能が小さいので、汎用性が高い。

組み合わせて使って楽しい。

いろいろ覚えていこう。

参考

orebibou.com

社長の家ですき焼きしたら、破壊神シヴァが現れた話。

f:id:karoten512:20180117195749j:plain

いきさつ

今年の冬、linuxの資格であるLPICのレベル1を取得した。

資格のレベル自体は大したことないのだけれど、

社長「お祝い何がいい?報酬とは別に、どこかお店つれってったげる」

社長「みんなで高いお店行こー!」

私「それなら」

私「すき焼きやりましょう」

私「社長の家で」

上司「それいいね!」

社長「それいいね!」

というわけで社長の家ですき焼きをすることになりました。

参加者

  • 社長

  • 社長の奥さん

  • 娘さん (2)

  • かろてん(私)

  • 私の上司

  • 社長宅に居候しているポルトガル人 ジェロ

  • ジェロの奥さん

謎の布陣ですき焼きをすることになった。

破壊神、がいた

社長の家につくと、

娘さんが大暴れしていた。

破壊神。

その言葉がぴったりだった。

社長が洗濯物をたたむ。

壊す

社長がお絵かき帳を渡す。

切り刻みまくる

社長が完成したパズルを渡す。

すべて蹴散らす

やばい。

創造と破壊は表裏一体とはよく言うが、

この子は破壊しかしない。

もはや社長の娘(2)ではない。

シヴァだ。

この子は破壊神シヴァ(2)だ。

社長が叫んだ。

社長「かろてん!シヴァをみててくれ!」

私の役割は、シヴァのおもりだった

このお守りで、

ボーナスの額が決まると言っても過言ではない。

私は全力でシヴァのお守りをすることにした。

私は役に立たない男であった

私の親戚には小さい子がいない。

いとこはみんな年上だ。

だから小さい子の扱い方を1ミリもしらなかった。

私がしたのは、

破壊活動の幇助と、

創造活動への啓蒙だ。

ハサミを渡す。

クレヨンを渡す。

のりを渡す。

私の活躍により、

破壊神シヴァ(2)は、

創造神ブラフマー(2)へ、

ありえない進化を遂げようとしていた。

きりきざまれた紙。

あり得ない配色に彩られた画用紙。

それが創造神の周りに、積もり積もっていく。

つまり、

破壊活動から破壊的創造活動に切り替わっただけで、

惨状は変わらなかった。

社長「かろてんだめだ!君は子守むいてないよ!」

今年のボーナスが、消えた。

私は迷子になった

すき焼きは美味しかった。

ガブガブ酒をのみ、

そろそろ帰ろうという時になって

上司と家に帰ることにした。

しかし、私は帰れなかった。

正確に言うと、

酒により極度に下がった空間把握能力で

空間が歪み、

最寄り駅の方向すらわからなくなった。

もともと私は道を覚えるのが得意ではない。

ポルトガル人はそのことを知っていて、

私のことをいつも、

「lost child(迷子)」

と呼んでいる。

私は助けをもとめた。電話で。

私「I’m completely lost child」

社長「OK. Don’t move」

私の記憶は、そこで途絶えている。

目が覚めると、そこは

社長の家だった。

社長はすでに出勤していた。

私は、

ポルトガル人におこされ、

ポルトガル人の奥さんにヨーグルトをもらい、

無言で食べた。

ポルトガル人といっしょに電車に乗り、

ポルトガル人といっしょに改札を出、

ポルトガル人といっしょに出勤した。

今日も

仕事頑張ろう。

curlからフォームデータを贈りたい時のオプションについて

curlの使い所

  • スクリプトから直接URLを叩きたい時
  • パラメータを変えてたくさんのリクエストを贈りたい時

こんなときはcurlが便利。

フォームデータを投げたいときは-data, -dオプション

curl --data form_name=form_value http://www.example.com/

POSTでフォームデータを送る。

なお、-Xでメソッド指定ができるので、上記は下記と同じになります。

curl -X POST --data form_name=form_value http://www.example.com/