僕らは JavaScript を知らない - シンボル Symbol
初めてプログラミングを触って、それからずっと2年くらい JavaScript 使ってますが、なかなか初心者から抜け出せないなあという思いがあり、恥を忍んで JavaScript の勉強記事を書くことにしました。たぶん何回か続きます。
参考:
シンボル Symbol
ES6 (実装はもう3年以上前?) では "Symbol" と呼ばれるプリミティブ(基本)データ型が追加されました。下記のコードでは、実際にシンボルを生成しています:
var sym = Symbol( "some optional description" ); typeof sym; // "symbol" sym.toString(); // "Symbol(some optional description)" var obj = { }; obj[sym] = "foobar"; Object.getOwnPropertySymbols( obj ); // [ Symbol(some optional description) ]
注意すべき特徵は、
- new 演算子で生成するわけではない
- 引数は任意。一度生成されたシンボルは自身のみと等しい
- シンボルの値そのものを取得することは出来ない
ということです。ほとんどの JavaScript デベロッパーには使う機会のない代物かもしれません。具体的な使用例を以下に見ていきましょう。
列挙定数
シンボルには「一度生成されたシンボルは自身のみと等しい」という特徴があるため、次のように定数として表すことが出来ます:
const EVN_LOGIN = Symbol( "event.login" ); const EVN_LOGOUT = Symbol( "event.logout" );
Redux の ActionTypes もシンボルで定義したいところですが、残念ながら、シンボルはJSONへのパースができないため Redux DevTool との相性が悪いということもあってか、推奨されていませんでした[^1]。
オブジェクトプロパティとしてのシンボル
シンボルをオブジェクトの特別なキープロパティとして使うことも出来ます。
const MEMBER = Symbol( "a" ); function save(value) { return save[MEMBER] = value; }
動作自体は以下と変わりありません:
function save(value) { return save.__member = value; }
シンボルをオブジェクトのキーにした場合、シンボルは Object.getOwnPropertyNames
メソッドからは秘匿されます:
var o = { foo: 42, [ Symbol( "bar" ) ]: "hello world", baz: true }; Object.getOwnPropertyNames( o ); // [ "foo","baz" ]
しかし、次のメソッドを使用することでオブジェクトのシンボルプロパティを取得することができます:
Object.getOwnPropertySymbols( o ); // [ Symbol(bar) ]
Well Known Symbol
シンボル関数オブジェクトにあらかじめ定義されたシンボルのことを Well Known Symbol と呼びます。
たとえば、 iterate
という Well Known Symbol は Symbol.iterate
として参照可能です。これらは、 JavaScript の組み込み関数の挙動をオーバーライドするために使用することが出来ます。
また、これらを @@
プレフィックスを付けて呼ぶ(@@iterate
)ことがあります。
var arr = [4,5,6,7,8,9]; for (var v of arr) { console.log( v ); } // 4 5 6 7 8 9 // for ... of ループの挙動を自作のイテレータでオーバーライド arr[Symbol.iterator] = function*() { var idx = 1; do { yield this[idx]; } while ((idx += 2) < this.length); }; for (var v of arr) { console.log( v ); } // 5 7 9
Symbol.for / Symbol.keyFor
シンボルを使用する可能性のあるコードがアクセスできるように、シンボルは外部のスコープに定義しなければなりませんが、 Symbol.for
メソッドを使えば、グローバルな空間における一意の文字列で管理することが可能です。
Symbol.for
メソッドは、文字列を引数にとり、その文字列ですでにシンボルが定義されていればそのシンボルの値を、定義されていなければ新たに作成し、シンボルの値を返します。
また、 Symbol.keyFor
メソッドでは、登録されたシンボルに渡された文字列を得ることが可能です。
var s = Symbol.for( "something cool" ); var desc = Symbol.keyFor( s ); console.log( desc ); // "something cool" // 再びシンボルを取得 var s2 = Symbol.for( desc ); s2 === s; // true
Symbol については以上になります。 余裕ができたら Well Known Symbol についても詳しく書くことにしましょう。
You Don't Know JS の日本語訳プロジェクトってないのかな?あったら教えて下さい。 もしなくて、日本語訳に興味がある方がいたら一緒にやりましょう。Twitterとかで連絡下さい。スペイン語翻訳のプロジェクトは見た記憶があるので許可はもらえると思います。
Amazon ECS Scheduled Tasks によるコマンドの定期実行
使い方
CMDに実行したいコマンドをカンマ区切りで入力し、Task Definition を作成。その他環境変数とかも
作成した Task Definition を Cluster の scheduled task にて設定。Cronかインターバルかを選択できる。
CloudWatch でログも見れるので便利
ActiveRecord IN clause
環境
$ rails -v Rails 5.1.2
基本形 where(カラム: [要素])
Model.where(id: [1,3,5])
enumのSymbolもそのままいける
Model.where(status: [:active, :inactive])
参考:
【SQL】今週の日曜日・今週の土曜日を求める
メモ:
CURRENT_DATE - interval (DAYOFWEEK(CURRENT_DATE) - 1) day AS THIS_SUNDAY
日曜日始まりとする。
今日の曜日インデックス(DAYOFWEEK(CURRENT_DATE)
)から日曜日の曜日インデックスを引くと、今日が日曜日から何日目かが分かる。
CURRENT_DATE + interval (7 - DAYOFWEEK(CURRENT_DATE)) day AS THIS_SATURDAY
土曜日の曜日インデックスから今日の曜日インデックスを引くと、土曜日は今日から何日目かが分かる。
もしかしたらそれ用の関数とか用意されてるのだろうか
Alpineでパッケージをインストールしようとしたらエラーがでたので解消する
メモ
ERROR: unsatisfiable constraints: py-pip (missing): required by: world[py-pip] ERROR: Service 'web' failed to build: The command '/bin/sh -c apk add py-pip' returned a non-zero code: 1
インストール可能なパッケージ一覧(インデックス)の更新オプションを付けると解消される (--update
)
apk add --update py-pip
Macでファイル内の文字列を再帰的に置換するコマンド
Re:dash SQLクエリ内で変数を使う方法
メモ。クエリが複数になるとエラーになるっぽい
SELECT id, (SELECT @date := huga) AS date, FROM hoge