Accessの日付処理はWindowsのロケール設定に依存しているが不完全なので問題を回避できない場合があるっぽい?

もう手もとにOffice 365 Soloなくて(仕事終わったんで解約した)、検証できないのでいろいろアレだけど一応書いておく。

AccessGUIから日付を取得しようとすると、Windowsロケールに依存した形式で返ってくるようなのだが、これを適切に取り扱う方法がない。

タスクバーの時計に曜日を表示したいので日付の短い形式のフォーマットを、yyyy/MM/dd '('ddd')'にしていたところ問題が出たのでいろいろ調べてみたのだが、AccessではWindowsに元から用意されていて選択可能ないくつかのフォーマット以外には対応していないようだ。

たとえば上記の場合日付は、2019/03/15 (金)のような形で表示されるが、これをFormat()の第1引数に入れても無視されるし、CDate()では型が違うとエラーになる。

具体的に試したコード、多分だけどこんな感じだったはず。

SELECT Format(#2019/03/15 (金)#, 'yyyy/MM/dd')

'2019/03/15 (金)'がそのまま返る。Format()関数はどうも、認識できないデータを渡すとそのまま返す?

SELECT CDate(#2019/03/15 (金)#)

これはエラーになる。

Windowsの設定を変更すればもちろん回避できるが。

VirtualBoxで、仮想アプライアンスのエクスポートをCLIでやる

半分くらいまで手動で(GUIで)やってからふと思い付いて調べたら、やっぱりできた。

VBoxManage list vms で名前取って、VBoxManage export <NAME> -o <NAME>.ova みたいな。

拡張子でエクスポートするファイルタイプを指定する形っぽい。.ovfで指定したら.vmdkもいっしょに出てきた。

多分GUI同様--ovf10がデフォルトだろうけど、不安な人は明示的に指定してもいいかも。

2018年に買ってよかったもの5つ

コーヒーメーカーとコーヒーミルと、水出しアイスコーヒー用のボトル

コーヒーメーカーは象印のEC-GB40ていう安いやつ。ドリップでそこまで味変わらんだろうと思ったので、ちゃんとしたドリッパーではなくコーヒーメーカー。じっさいそれで特に問題なくおいしい。

コーヒーミルはHARIOのMSCS-2Bていう手動のやつ。自動のはよさそうなのは高いのしかないし、手動でも困らんだろうと。アイスコーヒーの水出し用に大量に豆挽くときはけっこう困るので、早くも自動の買いたくなってきているが、手入れもしやすいしこれ自体はいい感じ。

水出しアイスコーヒー用のボトルはHARIOのフィルターインコーヒーボトルというやつ。水出しアイスコーヒーはとにかくうまいのでおすすめ。豆の量がそこそこ必要になるのだけ大変だが、その分の価値はある。60gの豆を手で挽いて、3杯分にしかならないのはつらいが。

コーヒーを豆で買うようになって、いろいろ飲み比べたりもして、なかなか充実したコーヒーライフになった。最近は決まったのしか飲まなくなってきているので、もうちょっといろいろ試したい気もするが。

除湿機

雨の日でも洗濯したいが、乾燥機までは厳しいので除湿機。三菱のMJ-120MX-Wってやつ。だいぶ安くなってたとはいえ3万もするし、今まで除湿機使ったことなかったのでどうかなと思ったが、かなり便利だった。雨が続くようなときに困らないのはもちろん、今まで洗濯する前に天気見てするか決めたりしていたのが、ほぼ気にする必要がなくなったことでかなりストレス減った。

地味に部屋の除湿もいい感じ。湿度高い夏場の雨の日とかに床がべたべたしていやな気分になるのを回避できるんだよね。

サブウーファー PM-SUB8

ブックシェルフタイプのスピーカーだけだと低音厳しいのでずっと欲しかった。さすがに低音すごいけど、集合住宅だとちょっと躊躇してしまうくらい出る。ボリュームをスピーカーの半分に、また夜間は使わないなどしてる。早く周りを気にせず音出せる環境にしたい……。

メタルみたいに元々音圧が強いようなのより、3ピースロックバンド的な音の方がサブウーファーのあるなしで違う。

コードレス掃除機

マキタのCL107FDSHWって安いやつ。紙パックで使ってる。うちはだいぶ狭いから一回の掃除機でコード付け替えるのってせいぜい2、3回で済んでたんだけど、それでもそれが0になると快適。ヘッドの性能はいまいちだが、個人的にはそこまで困らない。

Kindle Paperwhite

この辺にいろいろ書いたので割愛。とにかく読書が捗る。

Kindle Paperwhite マンガモデルを一ヶ月くらい使ってみての追加の感想 - 遠い叫び

Laravelでinput:checkboxのデフォルトでのチェックを実装する

ご存知の通りHTMLの仕様バグによりinput:checkboxは未チェック時、nameも送ってくれない。通常なら以下のようにして、フォームエラー時の再チェックを実装する。

<input type="checkbox" name="example" value="1" {!! old('example') == 1 ? 'checked="checked" : '' !!}>

デフォルトが未チェックであればこれで問題ないが、デフォルトでチェック状態にしたい場合はこれでは駄目だ。以下のように、引数なしのold()で、通常のフォーム表示なのか、フォームエラー時にリダイレクトされたのかを判断する。

<input type="checkbox" name="example" value="1" {!! empty(old()) || old('example') == 1 ? 'checked="checked"' : '' !!}>

もちろんこのチェックボックス以外のデータがない場合もempty(old())が真になるが、最低でもCSRFチェック用のフィールドは存在するため問題にはならないはず。

引数なしのold()がなにを返すかについてはドキュメントにはないので、以下のようにソースコードを辿る。

  1. old()Illuminate/Foundation/helpers.php::old().
  2. そこから、Illuminate\Http\Request::old()が呼び出されていて、その実体はIlluminate\Http\Concerns\InteractsWithFlashData::old()
  3. InteractsWithFlashData::old()からIlluminate\Session\Store::getOldInput()が呼び出されている。
  4. getOldInput()ではArr::get()されている。
  5. Arr::get()$keyが空の場合は$arrayをそのまま返している。

意外と道のりが長くてびっくりした。

Laravel Mixというかwebpackのコンパイルが、productionで重い件メモ

前提として、CSSはデフォルトにプラスα程度でデフォルトで入ってるBootstrapが重いく らい、JavaScriptが、Bootstrap入ってるファイルが別々に2つあってこっちが割と重い。

初回で13秒程度、変更検知でのコンパイルが6秒ほど。

一応developmentだと4秒未満、100ms未満。つまりproductionの場合に動いてるあた りが重いと。

いろいろ関係ありそうな部分をググったりソースコード読んで調べて試した結果、

  • processCssUrlsはほぼ関係なかった。
  • mix.sourceMaps()もおそらく。
  • mix.extract()もさっぱり。
  • UglifyJSはかなり重かった。が、これ外すのも……。
  • UglifyJSでunusedオプションを試したがこれも関係なかった。

UglifyJSをぜんぶなしにするのはアレなんで悩んでる。けど、外そうかな。

mix
  .options({ uglify: false })
  // ...

なおそもそも開発環境でもdevelopmentにしてるのは、単純にコンパイル済みをリポジ トリに突っ込む形にしてるから。これでdevelopmentでやってると、コミットの度に注 意しないとで面倒。

LaravelのViewのキャッシュの仕様

前の記事Blade::setEchoFormat()の挙動を確認していたときに、思うように反映されず、キャッシュかなあと思ったらキャッシュが原因だったということがあったので、Viewのキャッシュ周りの仕様を簡単に調べてみた。

結論から書くと、Viewのキャッシュは設定などによらず常に行われ、またキャッシュとテンプレートの最終更新日時のみ見て、キャッシュの方が古い場合のみ更新されるようだ。

なのでproductionじゃなくてもキャッシュされるし、Viewのコンパイル周りの設定が変わっても、テンプレート自体に更新がない場合はキャッシュが使われてしまう。

ついでに言うと、artisan cache:clearではクリアされない。

ちょっと扱いが面倒臭いな。

LaravelのBladeで{{ csrf_field() }}が通る理由

なにかの間違えで、{{ csrf_field() }}と書いていたんだけどそれが通るということがあって、{{ ... }}の仕様どうなってるのかなと思い確認した。

{{ ... }}は紆余曲折を経て、<?php echo e(...) ?>に変換されていた。e()はPHPerなら予想がつくだろう通りhtmlspecialchars()のラッパで、かつHtmlableインターフェイスを実装したクラスのインスタンスエスケープせずに通す、という仕様だった。まあ、よくあるやつだ。

なお調査ルートは以下の通り。

  1. {{, }}$BladeCompiler::contentTagsで定義されている。
  2. $BladeCompiler::contentTagsCompilesEchos::compileRegularEchos()で使用されている。
  3. compileRegularEchos(){{ ... }}から<?php echo e(...) ?>への変換が実装されている。
  4. ただし1, 2の関係が多少ややこしくて、$BladeCompiler::compilersBladeCompiler::parseToken()経由でCompilesEchos::compileEchos()が呼び出されて、そこからさらにcompileRegularEchos()が、という流れになっている。

CompilesEchosなどはBladeCompilerから5.4で分割されたようだが、もうちょっとリファクタリングして欲しい感じある。

あと、Htmlable周りはドキュメントに書かれていないが、これを知らないことにより{{ ... }}の使い方を間違えた場合に(多分)XSSしうるので、ドキュメントにちゃんと書いて欲しいなあ。{{ ... }}は常にエスケープするわけではないあたりを。

エスケープしない可能性があるのはHtmlableに関してだけではない。調査の中でBlade::setEchoFormat()という危ないメソッドの存在も知った。これを適当に書き変えちゃうと、変換先がe(...)に限らなくなってしまうので、最悪エスケープをなかったことにできたりもして危ない。まあ普通書き換えないだろうけど、もうちょっとなんとかならなかったのか。

また関連して{{{ ... }}}というのを見つけた。元々はこれと、{!! ... !!}だけだったのが、5から{{ ... }}が追加されたようだ。setEchoFormat()は見ないので安定しているかと思いきやe()を使ってるのでHtmlableは通すし、そもそもドキュメントからも消えているので多分使わない方がいい。

なお当初の疑問であった{{ csrf_field() }}についてだが、とりあえずいろいろ考えると{!! csrf_field() !!}などするのではなく{{ csrf_field() }}にするのが妥当そうである。が、そもそも5.6以降は@csrf, @methodなんてのができており、こちらを使うのがより妥当そうである。