■
font-feature-settingsにある組文字
組文字 - Wikipedia
font-feature-settingsにある、というのは奇妙な表現。
CSSでdligを有効にした結果として組文字として表示されるのはそのように個々のフォントでリガチャが設定されているからで、フォント依存の話でしかない。
ちなみにAdobeによると通常の「liga」リガチャに対して「dlig」は「discretionary(自由裁量の) ligatures」から来ているらしい。
PHP 8.3 で Randomizer に追加される float 取得関数の区間判別の実装
PHP 8.3 で Randomizer に浮動小数点数のメソッドが追加される。 gh#9679
最小値、最大値と区間の開閉を表す enum IntervalBoundary (ClosedClosed, ClosedOpen, OpenClosed, OpenOpen) を指定して浮動小数点値の乱数を生成できる。
当初この機能の実装では、区間の種類の判別を文字列比較して行っていた。
if (zend_string_equals_literal(bounds_name, "ClosedOpen"))
というのも pure enum を高速に比較する手段が今のところなく、名前を比較するしかないらしい。
これについてパフォーマンス的にどうなんだろう、と言うことでコードが修正された結果、こうなった。
bounds_type = ZSTR_VAL(bounds_name)[0] + ZSTR_LEN(bounds_name); ... case 'C' + sizeof("ClosedOpen") - 1:
enum の値は既に網羅されていて将来的に変わらないので、先頭文字と長さの和が固有になることを利用して O(1) でハッシュ化できる (PHP の string 長は既知のため) ということらしい。
0123456789ab ClosedClosed = 'C' + 12 = 79 ClosedOpen = 'C' + 10 = 77 OpenClosed = 'O' + 10 = 89 OpenOpen = 'O' + 8 = 87
しかし単純に6、7文字目に注目しても判別できそうだ。
こういうのはどうか。
bounds_type = ZSTR_VAL(bounds_name)[6]; ... case "ClosedOpen"[6]:
しかしこれは C++ では OK だが、C ではコンパイルできなかった。仕様はあたっていないものの、case の値を定数と見做してくれないらしい。
もちろん case 'O': // Closed[O]pen のようにすれば通りはするが、元のコードより見劣りする。残念。
■
Windows 10で、ディスプレイの電源を切る設定をしている。一定時間何も操作しないでいると画面の電源が切れる機能で、というか、設定していない人の方が少ないと思う省エネの機能だ。
ところが画面が暗くなって電源が切れるかと思ったらまた画面の電源が入ってしまう、という状態を繰り返すことがある。一旦この症状が出ると再起動するまで直らない。もちろんマウスの故障でカーソルが動いているなどではない。
もしやと思って以前から可能な範囲で確認していたのだが、GetTickCount()
で確認できる起動時間が0x7fffffffミリ秒(24.855日)を超えると起こるようだった。
64bit Windowsなのだが一体…
ICU の MessageFormat で同じパラメータを二度使うと U_ARGUMENT_TYPE_MISMATCH が出る
MessageFormat に渡すパターンの中でplural
で使ったパラメータをもう一度使おうとすると U_ARGUMENT_TYPE_MISMATCH になる。
<?php echo msgfmt_format_message('en_US', <<<'END' {count, plural, =0 {no items} one {1 item} other {{count} items} } END , ['count' => 12345]); if (intl_get_error_code()) echo intl_get_error_message(); // Inconsistent types declared for an argument: U_ARGUMENT_TYPE_MISMATCH
SymfonyやCakePHPのGitHub issueに出ていた回避策として、#
を使えばよい。
<?php echo msgfmt_format_message('en_US', <<<'END' {count, plural, =0 {no items} one {1 item} other {# items} } END , ['count' => 12345]); if (intl_get_error_code()) echo intl_get_error_message(); // 12,345 items
回避策はともかく、何故タイプミスマッチエラーになるのか、という説明がissueにはないのでICUのソースを追って調べてみた。
パラメータを単に{count}
と指定すると、文字列型になる。一方、{count, plural, ...}
とすると内部的には浮動小数になって、相互のタイプが非互換なため、メッセージのコンパイルがエラーになるようだ。
つまり#
は{count, number}
でも(冗長だが)よく、それならばplural
の外側にも適用できる。
実際、ドキュメントには#
は{××, number}
の略記とある。
<?php echo msgfmt_format_message('en_US', <<<'END' {count, number} {count, plural, one {item} other {items} } END , ['count' => 12345]); if (intl_get_error_code()) echo intl_get_error_message(); // 12,345 items
そもそもの話として単に{count}
とすると桁区切りされないので、普通は{count, number}
とすることになる。注意していればこのエラーも目にすることはなかったかもしれない。