javaのstatic { }とか{ }

スタティックイニシャライザ

クラスがロードされる際に呼ばれる。

static変数の初期化が関数を使って出来る!

static {

}

 

インスタンスイニシャライザ

コンストラクタと似ているが、

コンストラクタがA(), A(String name)などとオーバーロードされているとする。
その全てに共通の処理があるとき、普通はそれをメソッドにして、コンストラクタからそれを呼び出すが、
インスタンスイニシャライザならば、
先程メソッドに書いた内容をインスタンスイニシャライザに書くだけで良い。
コンストラクタから呼び出す必要が無くなるので呼び忘れも無くなる。

{

}

promamo.com

N Scala応用 型パラと変位

Javaでは全てのクラスがObject型のサブクラスだが、
ScalaではAnyが最上位のクラスで、次にIntなどの値型はAnyValクラス、参照型はAnyRefクラスのサブクラスになる。
図にすると、

http://joelabrahamsson.com/PageFiles/148/1310_1644.jpg

引用元:

Learning Scala part eight – Scala’s type hierarchy and object equality

 といった流れ。

 

型パラメータの前につくプラス+とかマイナスーは、変位指定という。
プラスは共変といい、javaでいうextends。
マイナスは反変といい、javaでいうsuper。

 

共変は引数に指定できず、反変は返り値に指定できない。

理由は下記リンク。

 

hogepiyo.hatenablog.jp

 

 

 

N Scala応用 関数 覚書

ScalaにはFunction0 ~ 22のトレイトがある。数字は引数の数で、0なら返り値のみ。
関数の作り方をきちんと追うと、まずこれらのトレイトを継承した無名クラスを作り、その中でapplyメソッドを宣言する、という流れ。この辺が関数型言語の特徴なのか?

applyメソッドは特別で、a.apply(x)がa(x)と等しい
ふつう、関数はfunc(x)のように呼び出すが、これを関数がインスタンスとなるScalaで書くとfunc.apply(x)となってしまう。
先程のようにapplyを省略することで普通の書き方になる。

 

Scalaは式ベースの言語であり、中括弧{ } (ブロックという)も実は式。
その返り値はブロック内の最後の式の評価結果なので、{ x + y }とx + yは同じ結果になる。

 

new Function2[String, Int, Int]の大括弧は型パラメータという。たぶん大体ジェネリクス

 

関数とメソッドの違いは、第一級の値であるかどうか。
つまり関数はオブジェクトになる。メソッドはならない
なので、引数としてメソッドを与えたり、メソッドが何かのプロパティを持つことは不可能。

 

高階関数とは、関数を引数にしたり、返り値にする関数のこと。

 

Scalaには末尾再帰最適化という機能がある。これは再帰によるスタックのオーバフローを防止してくれる機能。
末尾再帰による最適化 - Qiita が詳しい。

自分なりに説明してみる。
オーバフローの原因は、再帰する関数の返り値がreturn result + func(a) のようになっていること。
上記のように書くと、func(a)を評価したにresultと足し合わせる。
つまり、呼び出し元のアドレスと result変数をコールスタックに保持しておかなければならない。これでオーバフローする。

一方、return func(result, a) とすると、funcの返り値が呼び出し元の返り値そのものとなる。
この場合、返り値を計算するのに必要な変数は全てfuncに渡される。
つまり呼び出し元の情報を今後一つも必要としないので、もはや呼び出し元のアドレスも変数も必要ない。
よってコンパイラはこれをループに変換でき、オーバフローも回避できる。

 

WebStormでExpressのテンプレートのscriptタグにCannot resolve directoryと出る時

Expressでなくとも、フレームワークを使っているときあるあるだと思います。

javascript - Webstorm: "Cannot Resolve Directory" - Stack Overflow

Settings→Directories→publicを右クリックしてresource rootを左クリック

didinj/mean-angular4-chat-appについて

Building Chat Application using MEAN Stack (Angular 4) and Socket.io

上のリンクに順を追って書かれているけれど、色々抜けているのでForkしたほうがよい。

MEANスタックは、Mongo DB, Express, Angular, Node.js で構成される。

ExpressがDBアクセスとJSONAPI, Socket.ioのサーバなどのバックエンドを担当して、Angularは表示などフロントエンドをする。

ルーティングはexpressで行う。angularへのルーティングはng buildによって生成されたdist/index.htmlをrender()することになる。よって、起動コマンドはng serveではなくnode なんたらになる。好みでpackage.jsonのnpm startをnodeなんたらに変える。

Socket.ioのサーバはroutes/chat.jsで動いている。他のサンプルではbin/wwwに書いてあるものもあった。見通しが悪くなってしまうので専用のファイルを作ったほうが良いかもしれない。もしくは別プロセスで動かすのも吉かもしれない。

チャット入室時

入室後

  • http://localhost:4000のSocket.ioで発言を送受信
  • Angularがhttp://localhost:3000/chat (Express)に発言をDBにも反映するためにPOSTしている
    二度手間になるのでサーバのSocket.ioの受信イベントにまとめるべきでは?

socket.ioのメッセージがブロードキャストされていて、localStorageにあるroomと一致する時表示するという方法を取っている。セキュリティ的にもトラフィック的にもSocket.ioのroom機能を利用して不必要なところには送らないようにすべき。

JSではthisが関数の実行時のオブジェクトとなるので、.bind(this)によって宣言時のthisになるようにしている。io.onでbind()しているのはon内の関数のthisがSocket.ioとなってしまうためにangularがもつchatsにpushできないため。宣言時にはangularなのでbindしていれば問題なくpushできる。

JSON.stringify()とは、JSONJSON形式の文字列にするメソッド。逆の働きをするのがparse()。

 

 

N 実践HTTP 15~ 覚書

URL設計は基本的にモデルを基準にする。単独で操作するケースが少ないモデルは、そのモデルが従属するモデルのURLで行う。例を出すと、試験問題モデルは試験モデルのURLでよい。

 passport.serializeUser( (obj,done) => {} )でユーザオブジェクトをどのようにセッションに埋め込むかを規定できる。例えば省メモリ化するためにIDのみ埋め込むなど。

passport.initialize() middleware not in useとエラーが出た。メッセージそのまま、app.use(passsport.initialize())の前にpassport.authenticate()していたため。

Nodeでオブジェクトのプロパティを全てログ出力したいときは、util.inspect()を使う。引数はバージョンによって違うのでドキュメントを見る。

 npm package.jsonのscriptsのキーでコマンドを定義できる。npm startもそこで定義されている。

supertestによってExpressを起動することなく、routerオブジェクトをテストすることができる。

github-stubなど、OAuthのスタブのライブラリがある。

supertestではget()でGETリクエストして、expectでヘッダやbodyの内容をチェックできる。当然正規表現も使える。

 UUIDとは、全世界で(ほぼ)唯一の文字列。主キーが推測されてはいけないとき等に使える。Sequelizeではこのデータ型が用意されている。

複合主キーの順番は、インデックスによって結果を絞る順番と同じなので、慎重に設計する必要がある。

Sequelizeはsync()でCREATE TABLEする。つまり、外部キー制約に引っかからないために、A→Bという関係がある時はA.sync().then( () => { B.belongsTo(なんたら); B.sync()})のようにする必要がある。

npm start でsync()する場合、当然ターミナルは最後のSQLのログを吐いて、サーバとしての役割をするため終了しない。10分くらい待ってしまった。

UPSERTとは、レコードが存在しない場合はINSERT,存在する場合はUPDATEを行うこと。

router.get('/new', checker, (req, res, next) => {
 

このcheckerは別のrouter。checkerを通してから処理できるので、ログインが必要なページにルーティングするとき、このように記述してcheckerに認証処理等をさせる。checkerは委譲されたルーティングを元に戻さないとダメなので戻認証処理の後にnext()が必要。

slice(0, 255)によって255文字以下にする。

.map((b) => { return { a:b , c-key:1 }  })とすれば、DBで従属側に外部キーを一気につけられる。

 sequelizeは基本的にSQLインジェクションが不可能だが、where句で複雑なものが使いたい時に、条件を文字列で書くと可能になってしまう。そこはちゃんとエスケープかプレースホルダを使う。

レスポンスヘッダのX-Frame-Options:SAMEORIGINにより、外部サイトからアクセスできないようになる。

オープンリダイレクタ脆弱性とは、http://hoge.com/login?to=http://危険.xyzというリンクによってhttp://危険.xyzにリダイレクトするようなこと。
ログイン前にログインが必要なページに行く→ログインする→ログイン後にそこにリダイレクト のようなケースでは、ログインページでクエリを基にcookieにリダイレクト先を書いておき、ログイン後にそれを基にリダイレクトする。
そのときオープンリダイレクタ脆弱性をもつ可能性がある。対策はドメイン名より後のパスのみをクエリにし、かつcookieに書き込む前にスキーマが含まないことを確認すること。

<img src="URL"のURLは画像じゃなくても良い。画像が動的に生成されるページもあるので拡張子は考慮されないため。つまり勝手にGETできるということ。

CSRFとはjsで勝手にログインしているAmazonなどに向けてPOSTすること。トークンと呼ばれるセッションIDに紐付いた推測不可能な文字列(ハッシュで作れる)をhiddenで埋め込み、一緒にPOSTすることによって防ぐことができる。組み込みのモジュールを使っておけば問題ない。

Bootstrap Form おさらい - Qiita

N 実践HTTP ~14 覚書

PORT=8000 npm startはLinuxでの書式。
Windowsではset PORT=8000 & npm start とする。このsetコマンドとは、実行中の環境(プロンプト)でのみ有効な環境変数を設定するコマンド。「&(アンパサンド)」はコマンドの区切り文字。複数のコマンドを連続で実行できる。

 

ExpressはデフォルトではX-powered-by ヘッダにExpressを書き込む。
つまり閲覧者にExpressを使用していることを知られてしまう。
helmetモジュールによってこれを送信しないように設定できる。
他にもいくつかセキュリティに有用なHTTPヘッダがあり、helmetによって有効化される。
Node.jsのセキュリティ・チェックリスト | プログラミング | POSTD
なお、X-powered-byを隠したいだけならhelmetを使用せずapp.disable('x-powered-by');でも良い。

express実践入門 · GitHub

 

router.get('/', function(req, res, next) {});のnextはnext()のように使う。次に一致する、このルートの次に対象範囲が広いルートに処理を渡す。

Express - node Webフレームワーク | 日本語ドキュメンテーション

 

Applicationクラスのuseメソッドは、新しくrouterオブジェクトやミドルウェアを登録したり、設定をしたりするもの。設定にはテンプレートのパスやテンプレートエンジン、ログなどがある。

app.get('env')で、開発環境かリリース環境か取得できる。

 Node.jsでは、エンコードなどCPUに負荷がかかる処理はイベントループを妨げるためしてはいけない。Scalajavaなどマルチスレッドの処理系に委譲すべき。

log(2);やlog(4);をconsole.log('2');に置換したい時、検索 log\((\d)\) 置換 console.log('$1')とする。数字の部分を置換後に使うため、カッコでくくった。置換後は$1,$2のように何番目か指定して使用する。

mochaでのテスト

  1. mochaはtest/test.jsを参照する。mochaのコマンドは長いので、npm testだけでmochaが実行されるようにpackage.jsonのscriptsを編集
  2. test/test.jsにテスト用のコードを書く

webpack

  • webpackとは、JSのモジュールを一つのファイルにまとめるもの。通信量削減や名前空間の隠蔽などメリットがある。
  • entry.jsはルートとなる。javaで言うとMain.java。ここから参照を始める。
  • JSを変更したらwebpackでビルドという手順。Nodeが起動している間に変更されたら自動でビルドするという設定もある。
  • uglify(JSの圧縮)も設定で可能。

 JQueryを使用したjsを最初に読み込んでしまうと、HTMLが読み込まれていないためにconst para = $('#id')が取得できない場合がある。最後に書くか、遅延読み込みか、何らかの策を講ずる必要がある。

X-Requested-withによってajaxのリクエストか判定できる。