C Sharpens you up

http://qiita.com/yuba に移しつつあります

AngularjsがHaxeから扱えない理由

AngularjsはJavascript(以下JS)でリッチクライアントを書くためのMVCフレームワークです。JS MVCフレームワークはいま混戦状態で決定版はどれといいにくい状態ですが、確実に三強の一角ぐらいは占めていますね。

Angularjsについてもう少し知りたい場合はこちらのプレゼンテーションなどを。

さてそのJSは、今となっては人手でコーディングするには生産性が低すぎるから別のもっと良い言語からコンパイルして生成するようにしようぜという流れになっており、その「別のもっと良い言語」のことはAltJSと総称します。Haxe(ヘックス)はその代表格、その他にもCoffeeScript、TypeScript、Dart、JSXなどいろいろ個性ある言語がひしめいています。

当然、Angularjsを使ったアプリケーション開発でも、コード部分はJSでなくAltJSで書きたくないですかというのは当然の欲求で、実際にAltJSの採用例は多く、AngularJSと組み合わせるのに人気なのがTypeScriptです。TypeScriptはJSにクラスと静的型付けを盛り込んで正常進化させたと表現すべき言語でJSコードに上位互換性があり、なによりコンパイル結果として出力されるJSコードが素直で既存JSライブラリとも連携を取りやすいという利点があります。だから人気はうなずける。

でもHaxeもすごい言語。JSにクラスと静的型付けを盛り込んで(というよりはそういう位置づけのActionScriptを)正常進化させたものという点ではTypeScriptと似ているけど、Haxeは型体系がやばい。美しい。Enumが列挙体の枠をはるかに超えて代数的データ型になってしまっているって何言ってるのかわからないと思うので「Haxe Enum」でぐぐって検索結果の最初の10サイトを読んでみてくださいおもしろいから。

そのHaxeでAngulrajsの開発はちょっと無理

その美しいHaxeでクライアント開発したいな、Angularjsの開発できないかなと「Haxe Angularjs」でぐぐってみると全然これが引っかからないのですね。おかしい誰もやっていないなんてわけがないのに。

Haxeはちょっと前までは「出力されるJSコードが独自性強すぎてJSコード資産にならない(既存JSライブラリとも連携しづらい)」と言われていました。しかしHaxe 3.0になってからの出力コードは素直そのものでTypeScriptにも引けを取っておらず、これがAngularjsとの連携を阻んでいるということはありえません。

仕方ない、自分で書いてみるかと書き始めてみて、Angularjsを利用できない理由を理解しました。そうここまでが前振り。

Haxeはキーワードに$の文字を使えない

Angularjsはメソッド名や引数名に$の文字を多用していますが、これがHaxeのプログラム中で使えない文字なのです。HaxeはJSコードを出力するとき@:exposeアノテーションによってクラス名だけは別名出力させることが可能ですが、この@:exposeアノテーションはクラスにしか使えず、メソッド名だとか引数名だとかには適用不可能です。

引数名に関してはAngularjs側にも
http://js.studio-kingdom.com/angularjs/guide/di#1
$injectアノテーションという引数名変更に追従する仕組みがあるのですが、名前通りこの$injectというプロパティがすでに$の文字を含んでいたりして、やはりHaxeからは記述できません。結果として、$injectアノテーションの埋め込みをJSでべた書きすることになります。

引数だけでこれなのに各メソッドの名前もやはり問題となると… 使えませんねこれはとなるわけです。

Windowsのコマンドプロンプトでワンライナーを書こうとすると二重引用符がビョーキ

Windowsコマンドプロンプト(cmd.exe)でコマンド引数に空白を含む文字列を渡したいときは二重引用符でくくります。ここまではよく知られたノウハウ。

では、二重引用符を含む文字列を渡したいときは?、となると大半の人はあやしいはず。「¥でエスケープすればいい?」、いえ、¥がエスケープ文字になるのはUNIX系のシェルです。cmd.exeでのエスケープはどうなるかというとこれが公式情報が出ていない上に、どうもその隠し仕様も相当複雑なようで、こちらの記事

を読んでみても頭がくらくらするのですが、この知見を下敷きに、最近見つけた面白い動作の例をひとつご紹介します。

続きを読む

半二重のRS-485上に複数機器をつなげるModbus

BEMS機器の接続規格として最も古いModbusは1970年代からあります。その物理層は二線式のRS-485。半二重のシリアル通信を二線間の電圧差分で伝達するものです。

RS-485は単純なシリアル通信であり、ルーティング機能や衝突検知機能は持ちません。しかも半二重。半二重とはホスト2つを一対一でつないだとき、同時には片方からしかデータ送信ができないことを意味します。

そんなRS-485上で、Modbusは一対の二線式ケーブルにいくつもの(247台までの)機器をぶらさげるネットワークを実現しています。いったいどんな魔法を使っているのか?

魔法のからくりは、マスタースレーブ通信にあります。マスター機器が一台だけ存在し、

  • 通信を開始できるのはマスターだけ
  • 通信に応答してよいのはマスターに指名されたスレーブだけ
  • マスターから全員への通信(ブロードキャスト)には誰も応答してはいけない

というルールで衝突を防いでいるのです。

この仕組み上、機器はリアルタイム情報を中枢へアップロードするという仕組みは構成できません。あくまで、中枢が各機器へひとつずつ状態を聞いて回るという手順になります。

そのため参加機器が増えると(といっても247台が上限ですが)、最大19200bpsしか出ない通信帯域の中では状態取得頻度が上げられなくなるという性質があります。

あわせてどうぞ【BEMS技術】

5Lと3Lのバケツで4Lの水を作る問題・人力で解く編

就活シーズンだからかこの記事が検索されることが増えてきたので、プログラムではなく人の頭で答にたどり着く方法をまとめておきます。

問題は

5Lと3Lのバケツで4Lの水を作ってください。

です。暗黙の条件として、バケツから水を半分だけこぼすような操作はできません(円柱のドラム缶や角柱の石油缶なら可能でしょうが、バケツは円柱ではありません)。

続きを読む

DHCPで立てた社内サーバにマシン名でアクセスできるようにする

Windowsを使えばよろしい。
…で終わってしまうのでLinuxでもマシン名でホストアクセスを受け付けるようにする方法。

ドメインがexmaple.comでマシン名がmyhostだったら、dhclientの設定ファイルに次の設定を加えます。

send fqdn.fqdn "myhost.example.com";
send fqdn.server-update on;

dhclientの設定ファイルはディストリビューションとアダプタデバイス次第ですがCentOSなら/etc/dhclient-eth0.confなど。

次回DHCP取得時、DHCPサーバがDNSにマシン名を登録してくれます。

EBeanのトランザクションがtry-with-resources構文で書けるようになります

Play!(2.2以前)も採用している軽量O/RマッピングライブラリEBeanに出していたプルリクエスト*1が通ったので手前味噌。

これまでEBeanでは、トランザクションはtry-finallyで書くのが基本でした。

 Ebean.beginTransaction(); 
 try { 
        Order order = Ebean.find(Order.class,10); ...
 
        Ebean.save(order);
 
        Ebean.commitTransaction();
 } finally { 
        Ebean.endTransaction(); 
 }

Java7にはtry-with-resourcesという構文があり、finallyやendTransactionを自分で書かなくてよくなるというものなのですが、EBeanのトランザクションはその対象ではありませんでした。Closeableインターフェースを実装していなかったからです。

Closeableインターフェースを実装するというだけのプルリクエストを出していたのですが今回受理され、EBean 3.2.6からはこういう書き方が可能になります。

 try(Transaction tran = Ebean.beginTransaction()) 
 try { 
        Order order = Ebean.find(Order.class,10); ...
 
        Ebean.save(order);
 
        tran.commit();
 }

ちょっとスマートになりますね!

3.2.6がリリースされたらPlay!の各バージョンからもbuild.sbt(またはBuild.scala)に

"org.avaje.ebeanorm" % "avaje-ebeanorm" % "3.2.6",

の一行を書き加えることで利用できます。

*1:オープンソースソフトウェアに独自に改良を加えたとき、本家にその改良の採用を依頼すること。開発者向けSNSGitHubの機能です。