やろーじだい

ブログと技術メモです。なにかあればより詳細に書こうということで最初は雑に書くようにしています。質問・要望等あれば Twitter かコメントに下さい。

ClojureScript: :optimizations :advanced で外部ライブラリを用いた時に起こる問題への対処

問題

外部ライブラリを用いて以下のように ClojureScript で実行する場合に

(-> (js/LibHoge. args))
    (.run)

ClojureScript の build の config で :optimizations :advanced にした時に以下のようなエラーが発生する。

TypeError: (intermediate value).Kc is not a function
    at Object.pl ((index):676)
    at Object.<anonymous> ((index):632)
    at Object.componentDidMount ((index):43)
    at commitLifeCycles ((index):197)
    at B ((index):220)
    at A ((index):218)
    at t ((index):217)
    at x ((index):216)
    at y ((index):215)
    at D ((index):214)

これは .run という関数が、 ClojureScript のコンパイル時の外部ライブラリとの名前解決がうまくいかず .Kc という名前に単独で置き換わってしまうことで起こっていた。 解決策がわからず長いこと苦しんだ。

解決策

この記事 Using JavaScript libraries in ClojureScriptReferencing a library outside your compilation で言われている通りのことをすることで解決した。

まず以下の用に html の head 部分等にライブラリを埋め込む。(以下は ClojureScript での例)

[:script {:type "text/javascript" :src "/path/to/Lib.js"}]

更に project.clj の ClojureScript の :optimizations :advanced にしている設定に :externs でライブラリへのパスを通す。

:compiler {:main "..."
           :output-to "..."
           ...
           :optimizations :advanced
           :externs ["/path/to/Lib.js"]}

これらを行った上で ClojureScript のコンパイルを行うと、

WARNING - name define is not defined in the externs.

 WARNING - accessing name window in externs has no effect. Perhaps you forgot to add a var keyword?

といったかなりの量の警告を出されるが、最終的にはうまく言っている。多分 header に挿入した部分を見た時に WARNING が出て、それを解決するために externs 宣言の方の設定が利用されているようだが、あまりよくわかってない。

メモ OSX: opencv での color.hpp のエラー

起こったこと

opencv 使っていろいろやっていたらコードを変更していないタイミングで突然エラーが出るようになった。

cv2.error: OpenCV(3.4.2) /Users/travis/build/skvark/opencv-python/opencv/modules/imgproc/src/color.hpp:253: error: (-215:Assertion failed) VScn::contains(scn) && VDcn::contains(dcn) && VDepth::contains(depth) in function 'CvtHelper'

原因と対応

Finder などでデータセット一覧を見ていた時に .DS_store が作られてしまい、 imread にそれを渡してしまっていた。削除して .DS_store を作らないようにした。

defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true

また、設定後再起動が必要だった。

備考

今回は .DS_store が原因だったが同様のエラーの場合は何か画像以外のデータを誤って渡してしまっている可能性があるので確認する。

OSX ターミナル上での長い処理が終わったあとに通知する

やりたいこと

長い処理を待っている内にインターネットを見てしまい終わったことに気が付くのが遅れたりやっていることを忘れてしまうことがよくある。 そのため処理が終わったら音と、音が出せない時用に同時に視覚的に分かるように通知して欲しい。

方法

terminal-notifier を利用する。

install

$ brew install terminal-notifier

設定と使い方

alias bell="terminal-notifier -sound default -message 'Process finished'"
$ long_process; bell

備考

Linux 等を使っている人は node-notifier が使えるはず。 実際に試していないので参考までに OSX で通知を出してみた流れを記録しておく。

# 環境
$ npm -v
6.4.1
$ node -v
v10.9.0
# インストール
$ npm i -g node-notifier-cli
# 実行 -m=message -s=sound
$ notify -m 'Process finished' -s default