休日ワイ
ワイ「(カタカタカタカタカタ・・・)」
ワイ「(ッターーーーン!!!)」
ワイ「あっ、ぜんぶ消えてもうた」
娘(4歳)「パパ?」
娘「私のお願いしたシステム、作ってくれた?」
娘「曜日によって色々なメッセージが表示されるシステム」
ワイ「おお、鋭意製作中やで**(震え声**」
ワイ「今、休日かどうかを表示する機能のコーディングを開始したところや」
// 曜日番号を取得。
const dayNumber = new Date().getDay();
ワイ「まず、↑ここで曜日の番号を取得して」
ワイ「dayNumber
っていう名前を付けてんねん」
ワイ「ちなみに、番号と曜日の対応は・・・」
0 → 日曜日
1 → 月曜日
2 → 火曜日
3 → 水曜日
4 → 木曜日
5 → 金曜日
6 → 土曜日
ワイ「↑こんな感じやな」
ワイ「つまり、0
と6
が土日やからお休みやねん」
娘「うんうん」
ワイ「せやから・・・」
const isHoliday = dayNumber === 0 || dayNumber === 6;
ワイ「dayNumber
が、0
または6
の場合は」
ワイ「変数isHoliday
がtrue
になるようにしてんねん」
娘「なるほどね」
娘「逆に0
か6
以外の場合はisHoliday
がfalse
になるんだね」
ワイ「せや」
ワイ「それで、isHoliday
がtrue
なのかfalse
なのかによって」
ワイ「表示する文字列を変えるんや」
let dayText;
if (isHoliday) {
dayText = "お休み";
} else {
dayText = "平日";
}
ワイ「↑こうやな」
娘「パパ、let
を使わないで?」
ワイ「え・・・・・?」
娘「const
しか使わないで?」
ワイ「なんで・・・・・?」
娘「const
なら再代入されないから多少の安心感があるけど」
娘「let
だと、どこかで変な値が再代入されそうで」
娘「とっても不安なの・・・」
ワイ「ええ・・・・・?」
娘「コードを読むときも、変数の中身が変わる可能性を意識して読まないといけないから」
娘「疲れちゃうし・・・」
ワイ「ああ・・・」
娘「もっと言うと、const
でも不安なくらいなの」
娘「const
で宣言した変数でも、オブジェクトのプロパティは上書きできちゃうからね」
娘「だから、let
なんてもう耐えられないの」
ワイ「そうなんか・・・・・」
条件分岐したい時はどうする
ワイ「でもな、娘ちゃん・・・」
let dayText;
if (isHoliday) {
dayText = "お休み";
} else {
dayText = "平日";
}
ワイ「↑こんな感じで、if文で条件分岐して」
ワイ「それによって代入する値を変えたい時はどうすんの・・・?」
const dayText = if (isHoliday) {
"お休み";
} else {
"平日";
}
ワイ「↑こんな感じか?」
娘「いや、それだとエラーが出ちゃうね」
娘「if
文は、文だから値を返せないの」
ワイ「ほえぇ・・・」
娘「だから、そういう場合は・・・」
const dayText = isHoliday ? "お休み" : "平日";
娘「↑これでいいんじゃない?」
ワイ「いや、三項演算子は・・・」
ワイ「宗教上の理由で使えへんねん」
娘「そっか」
娘「じゃあ・・・」
const dayText = (() => {
if (isHoliday) {
return "お休み";
} else {
return "平日";
}
})();
娘「↑これはどう?」
ワイ「何これ」
娘「関数をその場で作って実行して、"お休み"
または"平日"
と言う文字列を返してるの」
娘「isHoliday
がtrue
なのかfalse
なのかによって」
娘「返す文字列が変わる・・・」
娘「そんな関数だね」
ワイ「関数をその場で作って実行・・・?」
ワイ「ぐぬぬ・・・」
ワイ「こんなんを頻繁に書く自信ないわ・・・」
娘「仕方ないなぁ」
娘「じゃあ」
娘「値を返せるif
みたいな関数を作ってあげるね」
関数iff
娘「はい、どうぞ!」
const iff = condition => {
const thenMethod = thenFunc => {
const elseMethod = elseFunc => {
return condition ? thenFunc() : elseFunc();
}
return { else: elseMethod };
};
return { then: thenMethod };
};
娘「if
は予約語だからiff
って名前にしたよ」
ワイ「何これ」
ワイ「ぜんぜん読めへんけど」
娘「うーん」
娘「とりあえずね・・・」
const dayText =
iff(isHoliday)
.then(() => "お休み")
.else(() => "平日");
娘「使い方は↑こんな感じ」
ワイ「おお、使い方は割とシンプルやな」
ワイ「なんか、Elmのif
式に似てるな」
dayText =
if isHoliday then
"お休み"
else
"平日"
ワイ「Elmだと↑こうやもんな」
ワイ「そうか、Elmのif
は式だから値を返せるんやな」
娘「うん」
娘「おんなじ感じだね」
娘「っていうか真似したんだけどね」
ワイ「でも娘ちゃん」
ワイ「なんか処理した結果を返したい場合はどうするん?」
ワイ「例えばif
文で言うと・・・」
let dayText;
if (isHoliday) {
const a = "お";
const b = "休";
const c = "み";
const holidayText = a + b + c;
dayText = holidayText;
} else {
const a = "平";
const b = "日";
const weekdayText = a + b;
dayText = weekdayText;
}
ワイ「↑こんな感じで」
ワイ「文字列を結合してから使いたい場合とか」
娘「そういう場合は・・・」
const dayText =
iff(isHoliday)
.then(() => {
const a = "お";
const b = "休";
const c = "み";
const holidayText = a + b + c;
return holidayText;
})
.else(() => {
const a = "平";
const b = "日";
const weekdayText = a + b;
return weekdayText;
});
娘「↑こんな感じだね」
ワイ「そうか」
ワイ「then
メソッドやelse
メソッドに渡す関数の中で」
ワイ「return
で値を返せばええんやな」
娘「そうそう」
これでlet
なしで行けそうだが・・・?
ワイ「ありがとうやで娘ちゃん」
ワイ「これでlet
なしで行けそうや」
ワイ「次は曜日に合わせたメッセージを表示する機能や」
ワイ「(カタカタカタカタ・・・)」
ワイ「・・・あれ!?」
let dayMessage;
switch (dayNumber) {
case 0:
dayMessage = "日曜日やで!ゆっくり休んでや!";
break;
case 1:
dayMessage = "月曜日やで!今週も頑張ろうな!";
break;
case 2:
dayMessage = "火曜日やで!";
break;
case 3:
dayMessage = "水曜日やで!";
break;
case 4:
dayMessage = "木曜日やで!";
break;
case 5:
dayMessage = "金曜日やで!もう少しで休みや!";
break;
case 6:
dayMessage = "土曜日やで!明日も休みやで!";
break;
default:
dayMessage = "曜日番号がおかしいで!";
break;
}
ワイ「↑この部分どうしよ・・・」
ワイ「let
使ってもうたわ・・・」
ワイ「switch
文のときは使いたくなるなぁ・・・」
娘「仕方ないなぁ」
娘「じゃあ」
娘「switch
っぽくて値を返せる関数も作るね」
関数switchf
娘「はい、できたよ!」
const switchf = switchVal => {
const caseMethod = (funcToDo) => caseVal => {
const isFixedNow = !funcToDo && switchVal === caseVal;
const thenMethod = (funcToDo, isFixedNow) => thenFunc => {
const defaultMethod = (funcToDo) => defaultFunc => {
return (funcToDo || defaultFunc)();
};
return {
case: caseMethod(isFixedNow ? thenFunc : funcToDo),
default: defaultMethod(isFixedNow ? thenFunc : funcToDo)
};
};
return { then: thenMethod(funcToDo, isFixedNow) };
};
return { case: caseMethod() };
};
娘「switch
も予約語だからswitchf
って名前にしたよ」
ワイ「これまた訳わからんコードやな」
娘「使い方は↓こんな感じ」
const dayMessage =
switchf(dayNumber)
.case(0).then(() => "日曜日やで!ゆっくり休んでや!")
.case(1).then(() => "月曜日やで!今週も頑張ろうな!")
.case(2).then(() => "火曜日やで!")
.case(3).then(() => "水曜日やで!")
.case(4).then(() => "木曜日やで!")
.case(5).then(() => "金曜日やで!もう少しで休みや!")
.case(6).then(() => "土曜日やで!明日も休みやで!")
.default(() => "曜日番号がおかしいで!");
ワイ「ほええ、今回も使い方は簡単なんやな」
娘「うん」
ワイ「でもさ、それくらいならただのオブジェクトか配列でも良くない?」
const dayMessageMap = {
0: "日曜日やで!ゆっくり休んでや!",
1: "月曜日やで!今週も頑張ろうな!",
2: "火曜日やで!",
3: "水曜日やで!",
4: "木曜日やで!",
5: "金曜日やで!もう少しで休みや!",
6: "土曜日やで!明日も休みやで!"
};
// または
const dayMessages = [
"日曜日やで!ゆっくり休んでや!",
"月曜日やで!今週も頑張ろうな!",
"火曜日やで!",
"水曜日やで!",
"木曜日やで!",
"金曜日やで!もう少しで休みや!",
"土曜日やで!明日も休みやで!"
];
ワイ「↑これでも、曜日番号を元にメッセージを取得できるで」
娘「まあね」
娘「でもswitchf
関数ならdefault
メソッドもあるよ」
ワイ「ああ、なるほど」
ワイ「どのケースとも一致しなかった場合のことも指定できるわけか」
ワイ「それはええかもね」
ワイ「ありがとうやで、娘ちゃん!」
これで何とかなりそう
ワイ「これで何とかconst
だけで行けそうや・・・」
ワイ「それにしても」
ワイ「娘ちゃんの**『再代入できる隙を作らない』**という強いこだわり・・・」
ワイ「感動したわ・・・!」
娘「てへへ」
ワイ「関数も、2つも作ってくれてありがとうな」
ワイ「お礼にこのお菓子とジュースをあげるから、向こうの部屋で飲んできいや?」
娘「わーい、ありがとうパパ!」
ワイ「ゆっくり飲んで来てな!」
娘「うん!」
ワイ「・・・よし、行ったな」
ワイ「これで再代入し放題や!!!」
ワイ「手続き大好きや!!!」
ワイ「副作用?そんなん知らんわ!!!」
よめ太郎「(クズやん)」
〜おしまい〜