JavaScript で 0 と 空文字を == で比較すると true になる

先日、JavaScript でこんな感じのコードを見かけました。

if (val == null || val == '') {
  // 値がないときの処理
}

値が null か空文字かをチェックするコードです。おそらく文字列を想定していたと思われますが、実際は変数に数値が代入されていました。

空文字と 0 を 等価演算子 (==) で比較すると true になるため、ここでは 0 が来たときに想定通りの挙動にはなりません。

なので、ここでは 厳密等価演算子 (===) で比較します。

0 == '' //=> true
0 === '' //=> false

先のコード例はこうなります。

if (val == null || val === '') {
  // 値がないときの処理
}

ちなみに、変数が undefined の場合は null との等価演算子で引っ掛けられるので、ここはそのままで OK です。

undefined == null //=> true

現場からは以上です。

(2019/03/15 追記)

こちらに詳しくまとめられてました。

phiary.me

古い iTunes で iOS をアップデートしてはいけない (iTunes 12.8.x / iOS 12 の例)

恥ずかしながら、我が家の MacBook Air はとても古いです。

Late 2010 モデルで OS は Max OS X Yosemite (10.10.5) です。現時点では iTunes 12.8.1.3 がインストールされています。

今さらですが、iPhoneiOS を 11 から 12 にアップデートしようとしました。これまで、この MBA を母艦として、iPhone のデータをバックアップし、その流れで iTunes 経由でアップデートしていました。

しかし、今回はアップデート中に「不明なエラーが発生しました」と表示されて、iPhoneリカバリモードから復帰せず...。バックアップから復元を試すも同様のエラー。万事休す。

で、週明けに Genius BarMacBook でアップデートしたところ、あっさりとアップデートが完了。データはそのまま。ひと安心...。自分の代わりに Genius BariPhone を持って行ってくれた妻に圧倒的感謝🙏

2019/03/12 時点の見解

(いろいろ誤りなどあるかもしれませんので悪しからず)

まず、iTunes 12.8.x は iOS 12 に対応していないようです。このバージョンの iTunesiOS 12 をアップデートしようとするとだめっぽい。そして、iOS 12 に対応していると思われる iTunes 12.9.x はおそらく OS X Yosemite (10.10.5) には来ない。さらに、現時点で新しいバージョンである macOS Mojave はこのモデルの MBA にはインストールできない。(High SierraSierra はできるかもしれないが試してない)

そもそも、これらの新しい macOS をインストールするには、まず El Capitan をインストールする必要があるっぽいです。しかし、El Capitan はすでに公開されていない。

つまり、我が家の MacBook Air は完全にオワコンであるわけです。というか、今までよく頑張ったねと言ってあげたい。

まとめ

これまで、あまり深く考えずに惰性でバックアップやアップデートをしていましたが、今回の件で iOS をアップデートするときに我が家の MBA は使えないことが分かりました。今後は iPhone から WiFi 経由 (OTA) でアップデートしようかと思います。また、バックアップから復元するときにもこの MBA は使えないと思われます。なので、バックアップ先に iCloud を利用しようかと。200GB (月額400円) あたりのストレージプランをファミリー共有で使う感じ。

というか、このご時世、iPhone のバックアップを PC に取ってるひとっているんだろうか...。ようやく世間に追い付いた感。

その他

古い OS や iTunes を使っていることがそもそもよくないのですが、iOS が対応していないとかアップデートができないということであれば、作業前に警告を出して欲しい。アップデートを開始してしまうと文鎮化待ったなしなので...。

Eclipse デバッグメモ

このスライドがとても参考になるので、メモ。

www.slideshare.net

実は、Q5 の Eclipse で実行中の変数の値を書き換えられることをつい最近まで知らなかったという...。Visual Studio でできるのは知ってたけど、まぁ必要に迫られることがなかっただけかもしれない。

あと、Q31 を応用すると、簡易的に処理時間を計測できる。計測したいところの前後にブレークポイントを打ち、Breakpoint Properties で Conditional にチェックして以下のように書く。

System.out.println(System.currentTimeMillis());
return false; // ブレークポイントで停止させない

これでブレークポイントを通過したときに標準出力にミリ秒が出力される。

GitBook Tutorial

以下の続編です。

GitBook on Windows - kntmr-blog

今回、GitBook のデモとして、チュートリアルのようなものを作成しました。コンテンツは随時更新しようかと思います。(たぶん)

gitbook-tutorial.firebaseapp.com

GitBook でビルドしたファイルを Firebase Hosting にデプロイしています。一応、ドキュメントとして使える見栄えにはなってるはず...。

ソースコードはこちら。

GitHub - kntmr/gitbook-tutorial


以下、備忘録。

プロジェクトが一覧に表示されない

Firebase Console からプロジェクトを作成して firebase init で初期化したところ、作成したプロジェクトが一覧に表示されない。とりあえず、以下でプロジェクトの設定は追加できる模様。

> firebase init --project <project_id>

また、firebase deploy すると 503 が返る。しばらく時間を置いて再度試したら普通にデプロイできた。新しく作成したプロジェクトが利用可能になるまで少し時間がかかるんだろうか...?もしかしたらプロジェクトが一覧に表示されないのもこれが原因?

GitHub X CircleCI で実現する DevOps に行ってきた

GitHub X CircleCI で実現する DevOps に行ってきました。簡単に所感をまとめます。

peatix.com

所感

GitHub と CircleCI のような CI ツールを組み合わせることで、コードやレビューをオープンにして、開発サイクルを早く安全に回すことができるというのがポイントなんだろうと思われます。今回はどちらかと言えば入門的な内容だったかと思いますが、資料やデモがあってとても分かりやすかったです。テストがなければ CI の意味はあまりないかと思ってましたが、日常の手作業を自動化するだけでも CI と言えるというのは目から鱗でした。

早速、CircleCI を試してみようかな。ちなみに CircleCI は、Jenkins や Concourse とはどこらへんが違うんだろうか。そのあたり聞いてみればよかったか...。

以下、メモから抜粋。ただ、話を聴くのに集中しててちゃんとメモが取れてません...。スライドが公開されたらリンクを貼っておきます。

(2019/02/06 CircleCI のスライドを追記しました)

GitHubとCircleCIで実現するDevOps

  • DevOps の背景
    • 開発スピードをあげたい / 改善サイクルを回したい
    • サービスの安定性や信頼性は保ちたい
  • 開発サイクルを安定して高速に回す
  • DevOps を実践している企業としていない企業の違い☆
  • DevOps の原則☆
    • 開発チームとインフラチームには壁がある
      • 目指しているものが違う (改善 / 安定)
    • 「失敗をなくす」から「失敗を早く見つけて直す」にマインドをシフトする
    • 個々の変更は小さくする
    • 計測によって問題を早期に発見する
  • CI/CD
  • CI とは☆
    • 共通のテストを実行できるメリットがある
  • CI でできること☆
    • テスト、ビルド、静的コード解析、脆弱性チェック、テストサマリー
    • テストがなくても CI はできる
      • 作業を自動化するだけでも CI と言える
  • CI が解決する問題☆
    • 実行するテストの粒度は設定で制御できる
    • 静的解析によるコードの標準化
    • テストが失敗するコードをマージブロックして master ブランチを安全に保つ
  • CD とは☆
    • デリバリは環境への資産の配備のみ
    • デプロイには人間の手が入る
      • そこを自動化すると継続的デプロイメントと言える
  • デプロイ作業を自動化することで属人化やヒューマンエラーを防ぐ
    • 最近は CI/CD の設定をコードで書く (バージョン管理できる)
  • GitHub
  • 議論やアクティビティを GitHub 上で
    • 組織内で知識や専門性を共有する
  • GitHub Flow
  • PR のメリット☆
    • さまざまな議論やフィードバック
    • 開発の透明性をあげる
  • PR に CI を組み込む
    • レビューとテストが通るものをマージする
    • 早い段階でエラーに気が付くことができる
  • CircleCI の最新機能
    • ワークフロー (パイプライン)
      • スケジューリング、承認
    • Docker サポート
      • 2.0 ではいちばん推してる
      • VM による CI より高速にビルド可能
      • 本番環境のコンテナと同じ環境でビルドできる
    • 多言語サポート
      • Docker イメージがサポートしている言語であれば使える
    • テスト環境を統一 (yaml)
      • 設定をコードで書くことでバージョン管理できる
    • SSH デバッグ
      • ビルドしたコンテナをキャッシュしておいて ssh でログインできる
      • テストの再現やコード修正ができる (修正をそのままpushできるわけではない)
    • デプロイ
      • 主要なプラットフォームにデプロイ可能
    • Orbs
      • config をパッケージ化 (共通化) できる
  • GitHub の中でもある程度は CircleCI の情報は見れる
  • レビューとビルドが通ったものだけ master にマージできるなどの制御が可能
  • GitHub Actions
    • GitHub 上のイベントをトリガーにしてワークフローを実行する
    • アクションは Docker コンテナで定義
    • 簡易な CI/CD はできる
    • CI/CD ツールと共存するものという位置付け
    • CI/CD 以外の日常の作業を自動化する
  • CircleCI Japan
    • 日本のマーケットは大きい (日本のユーザーが多い)
    • 海外拠点としては日本が初めて
    • 日本語サポート
    • ドキュメントの日本語化
  • あとで読む

codezine.jp

ユーザー事例 (サイボウズ)

www.slideshare.net

  • 国内DC & AWS
  • 最近はクラウドサービスの活用が多くなってきた
  • オンプレ開発基盤は導入、運用、外部クラウドサービスとの連携が面倒
  • クラウド開発基盤は社内ネットワークと連携しにくい
  • GitHub 導入
    • svn から移行
      • master を壊さずにレビューできる
    • PR
      • 変更理由やレビューの経緯がオープンになる
      • チーム外から PR できたり
  • CircleCI 導入
    • Jenkins から移行
    • コンテナ内ビルド
      • CircleCI 公式 Docker イメージが使える
  • GitHub 連携
  • Performance Pricing Plan (従量課金)
    • コンテナ数の課金より無駄がない
  • DevOpsQA
  • インフラも継続的に
    • 1日1回 CI で VPC を削除して再構築
    • ゼロから環境を作成できることを保証する

Vue.js で正数や小数のみ入力を許可するテキストボックスコンポーネントを自作してみる

正数や小数のみ入力を許可するテキストボックスを Vue.js のコンポーネントとして作ってみました。一般的には type="number" を使うといいのかもしれませんが、今回はもろもろの事情により type="text" を使います。あと、Vue.js らしいところはあまりないです...。

サンプルコード

正数のみ入力を許可するテキストボックス

テンプレートは次の通り。

template: `
  <input type="text" :size="size" :maxlength="maxlength" v-model="value" @keypress="validate" @input="value=format(value)" />
`

@keypress@input で制御する。イベントハンドラは次の通り。

methods: {
  validate (e) {
    const charCode = (e.which) ? e.which : e.keyCode
    if (charCode > 31 && (charCode < 48 || charCode > 57)) { // 数字入力のみ許可する
      e.preventDefault()
    } else {
      return true
    }
  },
  format (val) {
    if (!val) {
      return ''
    }
    const replaced = val.replace(/\D/g, '') // 数字以外を除去
    return replaced ? replaced : ''
  }
}

@keypress では、keyCode で数字入力のみ許可するようにしている。ただし、これだと IME の入力が制御できない。仕方がないので、@input で数字以外を除去して上書き。泥臭い。

正数と小数のみ入力を許可するテキストボックス

テンプレートは次の通り。

template: `
  <input type="text" :size="size" :maxlength="maxlength" v-model="value" @keypress="validate" @change="value=format(value)" />
`

こちらは @keypress@change で制御する。イベントハンドラは次の通り。

methods: {
  validate (e) {
    const charCode = (e.which) ? e.which : e.keyCode
    if ((charCode > 31 && (charCode < 48 || charCode > 57)) && charCode !== 46) { // 数字と小数点の入力のみ許可する
      e.preventDefault()
    } else {
      return true
    }
  },
  format (val) {
    if (!val) {
      return this.prevValue = ''
    }
    if (/^([1-9]{1}[0-9]{0,1})(\.\d{0,2})?$/.test(val)) { // ##.##
      return this.prevValue = val
    }
    if (/\.\d{3,}$/.test(val)) { // .### => .##
      return this.prevValue = (Math.floor(parseFloat(val) * Math.pow(10, 2)) / Math.pow(10, 2)).toString()
    }
    return this.prevValue
  }
}

@keypress では、keyCode で数字と小数点の入力のみ許可するようにしている。今回、整数部2桁&小数第2位という形式で制限している。@input だと厳しい感じだったので、@change でフォーカスが外れたタイミングでチェックしている。前回の正常値を data プロパティに保持しておいて、不正値が入力された場合は前回の正常値で上書きしている。泥臭い。

まとめ

どちらも最終的に泥臭い感じになりました...。もう少しスマートにしたいところ。

あと、今回初めて知ったのですが、KeyboardEventkeyCode プロパティなど、割とよく使われているだろうと思われるプロパティがいつの間にか非推奨になっていました。代わりに keycode を使う模様。

developer.mozilla.org

正規表現でカンマの3桁区切り

備忘録。金額表示などでよくあるカンマで3桁ずつ区切るアレ。正規表現で実現できることを知りました。便利なのでメモ。

"123456789".replace(/(\d)(?=(\d{3})+$)/g, '$1,'); //=> "123,456,789"

現場からは以上です。