投稿者「mod_poppo」のアーカイブ

Haxe を触ってみた感想

Haxe とは、プログラミング言語である。公式サイト

ちょっとだけ使ってみたので、感じたことを書きなぐっておく。

特徴

複数の言語にコンパイルできる(ターゲット一覧):

  • Flash (bytecode) / ActionScript
    • 言語仕様は ActionScript の影響を色濃く受けているっぽい
  • JavaScript
  • PHP
  • Java, C#, C++ などの静的言語

良いところ

  • 代数的データ型(enum)とパターンマッチ(switch 式/文)がある。
  • Haskell で言うところの newtype みたいなやつ(abstract)がある。
  • インライン関数がある。
    • 実行時コストを気にすることなく another level of indirection を導入できる。
    • 条件コンパイルと併用するといい感じに環境の違いを吸収できそう。
  • マクロがある。
    • 実際どの程度強力かは、あまり使い込んでいないので何とも…。

悪いところ

  • Java のように、すべての関数をクラスの中に書かないといけない。main 関数はどこかのクラスの static 関数で定義する。
    • Java のようにと言うか、直接的には ActionScript から受け継いだ仕様っぽい。
  • 型クラスや deriving がない。
  • 代数的データ型を == で比較できないのが地味に辛い(Haskell なら deriving Eq をやっておけば == で比較できる)。Type.enumEq は、中に enum じゃない物が入っていた場合 == で比較してしまうみたいなので、オブジェクトへの参照を含む enum どうしの比較が辛いことになる。
  • null の扱いがイマイチ。動的ターゲットと静的ターゲットによって微妙に違う。
    • Option<T> 型と Null<T> 型のどちらを使うか迷う。
    • NonNull<T> みたいなものが欲しい。
  • 標準ライブラリの細かい仕様が、ターゲットに依存する場合がある。具体的には正規表現の EReg
    • Write once, debug everywhere と言う感じ。
    • ターゲット依存の挙動を排除するために標準ライブラリの実装を肥大化させるか、ターゲット依存の挙動を許して標準ライブラリの実装をスリムにするかのトレードオフなので、やむを得ない面はある。
    • 条件コンパイル(#if#elseif#else#end)が使えるので、適宜切り分けるべし。
  • 簡単なデータ型を作る時に、クラス型anonymous struct 型か(enum 型か)悩む。
    • Static extension を使えば、 anonyomous struct 型や enum 型にもメソッドを追加できる。
    • 構築方法が new Hoge(33, 4) / {foo: 33, bar: 4} / Hoge(33, 4) という風に違うが、 abstract を使えば吸収できそう(全部 new Hoge の形で構築できるようになる、はず)。
    • 静的言語がターゲットの場合、 anonymous struct 型は効率が悪そうに見えるので避けるべきかもしれない。
    • 一方、 JavaScript がターゲットだとクラスよりも anonymous struct の方が良いのか…?と思ったり。

各ターゲットに関して

  • JavaScript
    • 等値比較を === ではなく == でやっているのがイケてない。null/undefined との比較ならともかく、数値とか文字列とかは === で良くないか。
  • C++
    • 動的言語って感じのソースコードを吐き出す。
      • クラスのメタデータ満載。名前(文字列)によるフィールドへのアクセスとか。
      • Structural subtyping や(C++ ではなく Haxe の)RTTI を使わない場合にこいつらを抑制する手段はないのか。
    • 行番号やスタックの変数の情報と思われるもの(HX_STACK_LINE, HX_STACK_VAR)はコンパイルオプションの -no-debug で抑制できる。
    • Null<Int>Dynamic になってる。
    • 全体的に、もっと静的言語っぽいソースコードを吐き出す余地はあると思う。

まあ、手書きのコードには敵わないにせよ、知らないターゲット言語でも「とりあえず動く」ものを吐き出せるというのはすごいと思う(null の扱いの違いや正規表現の非互換に目をつぶれば)。

Visual C++ での C99 complex

最近のVisual C++ではC99もある程度サポートしているらしい。

上記ブログによると、 complex.h の関数もサポートしているらしい。しかし、コンパイラーは _Complex 型をサポートしていない。_Complex 型をサポートしていないのに、 complex.h の関数をサポートしているとはどういうことか。一体、 complex.h の関数は何を受け取って何を返すのか。

確認のため、次のような簡単な C++ のプログラムを書いてみた。 続きを読む

wxWidgets をビルドする

wxWidgets とは、C++で作られたクロスプラットフォームGUIツールキットである。Windows, OS X, GTK+ などに対応している。商用版のある Q なんとかと比べて見劣りするとか言うんじゃないぞ

入手

開発中の最新版を入手しよう。wxWidgets のリポジトリは、現在 GitHub でホストされている。(ただし、Issue の管理は GitHub ではなく wxWidgets Trac を使っている。GitHub でのプルリクはできる)

https://github.com/wxWidgets/wxWidgets

続きを読む

C言語でなんちゃって2進数リテラル

こういうビットマップ(1ピクセルにつき1ビット)を、整数の配列としてC言語のソースコード中に埋め込みたい:

□□□□□
■■■■■
□■□■□
□■□■□
■□□■■
□□□□□

2進数リテラルがあればそれを使うという手があるが、残念ながらC言語には2進数リテラルがない(ちなみに、C++にはC++14から2進数リテラルが入った。また、独自拡張で2進数リテラルが使えるコンパイラーもある)。

というわけで、自分で作ることにした。要件としては

  • コンパイル時定数となる
  • 桁を空白で区切れる

がある。 続きを読む

LaTeX の \verb についてのメモ

導入

LaTeXをやったことがある人なら \verb コマンドはきっと知っているだろう。

例: \verb|hoge|hoge

例: \verb+foo bar+foo bar

亜種として、\verb の直後にスター * がついた版は、空白を可視化する(空白が ⎵ みたいな記号になる)。

例:\verb*+foo bar+foo⎵bar

この \verb というコマンドは、「TeXの特殊文字を無力化する」「任意の文字を終端として使える」という点で、非常に風変わりである。\verb コマンドを知ることは、TeXの字句解析のルール(カテゴリーコードとか)に対する理解を深めることに直結すると言っても過言でないだろう(たぶん)。というわけで、\verb について重箱の隅をつついた結果をここに書いておく。

なお、TeXにおける「カテゴリーコード」とかそういうアレはここでは解説しない(対象読者が謎)。

続きを読む

MSYS2 から Visual C++ (の環境変数を設定するバッチファイル)を叩く

2016年4月26日:「シェルでやる方法」を追記。

Windowsの開発環境には、環境変数を設定するバッチファイルが提供されていて、そのバッチファイルを実行すると PATH とかの環境変数が設定されるというパターンがたまにある。(スタートメニューに「環境変数を設定済みのシェルを起動する」ショートカットを登録するパターンの方がもっと多い気がするが)

MSYS2からこういう開発環境(というか、Visual C++)を叩きたい。もちろん、cmd.exe を使って

$ cmd //c "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat"

みたいなことをすれば vcvars64.bat (Visual C++用に環境変数を設定するバッチファイル)を実行すること自体はできるが、そこで設定された環境変数は呼び出し元のシェルに反映されない。 続きを読む

Raspberry Pi と gPhoto2 で一眼レフを叩く

Raspberry Pi (Arch Linux インストール済み)に一眼レフをUSBで繋いで制御してみよう。

gPhoto2のインストール

# pacman -S gphoto2

違うディストリ/パッケージマネージャーでも、何かしら gphoto2 みたいなパッケージはあると思う。

簡単な使い方

接続されたデバイスの一覧を見る:

$ gphoto2 --list-ports
Devices found: 3
Path                             Description
--------------------------------------------------------------
ptpip:                           PTP/IP Connection               
usb:001,005                      Universal Serial Bus            
usb:001,003                      Universal Serial Bus            

機種名を表示:

$ gphoto2 --auto-detect
Model                          Port
----------------------------------------------------------
Canon EOS 600D                 usb:001,005

EOS 600DというのはEOS Kiss X5のことで、同じ製品でも日本と海外で名前が違うとかいうアレだ。

パーミッションの罠

では、 gphoto2 --summary でもっと詳しい情報を取得してみよう。

$ gphoto2 --summary

*** Error ***
An error occurred in the io-library ('I/O problem'): No error description available
*** Error (-7: 'I/O problem') ***

For debugging messages, please use the --debug option.
Debugging messages may help finding a solution to your problem.
If you intend to send any error or debug messages to the gphoto
developer mailing list <gphoto-devel@lists.sourceforge.net>, please run
gphoto2 as follows:

env LANG=C gphoto2 --debug --debug-logfile=my-logfile.txt --summary

Please make sure there is sufficient quoting around the arguments.

なんかエラーが出た。

しかし、このエラーはハードウエアの問題とかgPhoto2の問題ということとも限らない。なぜなら、

$ sudo gphoto2 --summary

としてみたり、

$ lsusb | grep Canon
Bus 001 Device 005: ID 04a9:3218 Canon, Inc. EOS 600D / Rebel T3i (ptp)
$ ls -l /dev/bus/usb/001/005
crw-rw-r-- 1 root root 189, 4 Feb 14 18:23 /dev/bus/usb/001/005
$ sudo chgrp users /dev/bus/usb/001/005
$ gphoto2 --summary

みたいな感じで /dev/bus/usb/ほにゃらら/ほにゃらら のグループを変えてやるとうまくいく。つまり、USBデバイスのパーミッション的な問題だということだ。

そこで、 udev の設定をいじる。Arch WikiのDigital Camerasのページを参考にして、

# groupadd camera
# /usr/lib/libgphoto2/print-camera-list udev-rules version 175 group camera > /etc/udev/rules.d/40-gphoto.rules
# usermod -a -G camera (自分)

みたいなことをやったらうまくいった。(自分の環境だと 40-gphoto.rules というファイルは /usr/lib/udev/rules.d/40-gphoto.rules に既に存在したが、/etc/udev/rules.d/ に同名のファイルを置くとそっちの方が優先される。この辺は man udev を参照。)

設定を変えた後は再起動が必要かもしれない。

簡単な使い方その2

gPhoto2 で写真を撮ってみる:

$ gphoto2 --capture-image

写真を撮影&ダウンロード:

$ gphoto2 --capture-image-and-download

頑張れば露出とかシャッター速度とかいろいろ設定できそうだが、そういうのはまた今度。

Raspberry Pi じゃなくても

gPhoto2は別にRaspberry Piじゃなくても普通のLinuxとかあるいはOS Xでも動くのだが、お節介なリッチなデスクトップ環境とかが入っていると、そっちの方にカメラの制御権(?)を奪われてしまう場合があるので注意しよう。

~/.ssh/config

SSHでリモートホストにログインする際、ホストごとにユーザー名とかポート番号が違って(覚えるのが)面倒くさい!

$ ssh hoge@example.net
$ ssh -p 10022 user@example.com
$ ssh user2@192.168.11.5

そんなときは、 ~/.ssh/config を記述すれば、ホストごとにデフォルトのユーザー名とポート番号などを指定できる。

# User を指定
Host example.net
User hoge

# User と Port を指定
Host example.com
User user
Port 10022

# HostName で実際に接続するホスト名/IPアドレスを指定することもできる
Host hoge
HostName 192.168.11.5
User user2

書き方とかは man 5 ssh_config を参照。あるいはググればいろいろ用例が出てくる。

実は常識だったりするのかもしれないが、知らなかったのでメモしておく。