2011年12月21日水曜日

is_writable の実装探しの旅

pgpoolAdmin のインストール時のエラーの続き。

selinux が原因だったので、 is_writable の実装探しの旅に出ても結局分からなかったと思われる。
が、気になったので、実装探しの旅に出てみることにした。

emacs + cscope で読むことにする。
php のソースコードを展開して、cscope のファイルを作成。
$ cd php-5.3.8
$ find ./ -name "*.h" -or -name "*.c" > cscope.files
$ cscope -b -q -k
emacs で展開したディレクトリあたりを開いて、 M-x cscope-find-global-definition is_writable を実行。
まぁそう簡単には見つからない。M-x cscope-find-this-symbol is_writable でいくつか候補が。
その中でそれっぽいのが、
*** ext/standard/php_filestat.h:
<global>[39]                   PHP_FUNCTION(is_writable);
...
*** ext/standard/basic_functions.c:
ZEND_END_ARG_INFO[3194]        PHP_FE(is_writable, arginfo_is_writable)
宣言と定義っぽいのが見つかったが、マクロのようだ・・・

宣言っぽいほうを追っていくと
#define ZEND_FN(name) zif_##name
とか出てくる。zif_iswritable とか作られているのだろうか。

次に定義っぽい方を追っていくと、
const zend_function_entry basic_functions[] = { /* {{{ */
  [snip]
    PHP_FE(is_writable,       arginfo_is_writable)
となっている。
関数ポインタを持った構造体の配列?これを追うのは大変そうだ・・・そもそもの仕組み知らないし・・・呼び出し元が探せない・・・
という訳で、GDB でステップ実行してみることに。

http://d.hatena.ne.jp/anatoo/20111117/1321463886
を参考にまず、まずコンパイル。
$ ./configure --disable-all --enable-debug
$ make
でテスト用のスクリプト(~/test_is_writable.php)を作成。(前回通らないと思ってたが Web 経由だとユーザが異なっていてパーミッションの問題だったかも・・・パーミッション確認後、再度実行したらこのスクリプトは true となった)
<?php
echo is_writable('/usr/local/etc/pgpool.conf');
次に、GDB で実行。
$ gdb sapi/cli/php
(gdb) break zif_is_writable
Breakpoint 1 at 0x509b30: file /usr/local/src/php-5.3.8/ext/standard/filestat.c, line 1092.
(gdb) run ~/test_is_writable.php
後は、s と n で辿っていく。
ext/standard/filestat.c:782 の php_stat が実装のようだ。
さらに入っていくと、
eck_open_basedir_ex (path=0xb03350 "/usr/local/etc/pgpool.conf", warn=1)
    at /usr/local/src/php-5.3.8/main/fopen_wrappers.c:297

 if (PG(open_basedir) && *PG(open_basedir)) {
あたりだろうか。
PG の定義は、
# define PG(v) (core_globals.v)
extern ZEND_API struct _php_core_globals core_globals;
_php_core_globals の open_basedir が設定されているかどうかを見ているっぽい。
が、open_basedir が分からない。
ググッて見ると、php.ini にそういう項目があるようだ。
このあたりをいじればいけるかと思ったがそうでもなかった。

テストスクリプトだと true となるのでこのあたりで断念。
結局追えなかった・・・

2011年12月12日月曜日

pgpoolAdmin のインストール時のエラー

今回は、pgpoolAdmin を検証するためにインストールしていた時に嵌まったことを。

pgpoolAdmin を展開後、http://www.example.com/pgpoolAdmin/install/index.html にアクセスしてインストール作業を続けるわけだが、/usr/local/etc 以下の pgpool.conf や pcp.conf が "Write access denied" となっていて先に進めない。

ファイルのパーミッションや所有者を確認してみるが特に問題はなさそうだ。
PHP で作られているようなので中身を見てみることにした。

install/checkParameter.php 60
if (!is_writable($pgpool2_config_file)) {
  $msgPgpoolConfigFile = 'Write access denied';
  $error = TRUE;
}
となっている。

実行ユーザを調べるために
echo `id`;
を埋め込んでみるも、想定通りのユーザで動いてそうだ。

スクリプトからパーミッションを取得するために
var_dump(stat($pgpool2_config_file));
を埋め込んでみるも、
["mode"]=> int(33188)
となっており、8 進数で 100644 となり、これも問題なさそう。

is_writable のみを記述したテストプログラムを作成してみるが、この時点で false が帰る。後日、動かしてみたら true だった。おそらくこれはパーミッションだったかな・・・
これは困った。is_writable の実装を探す旅にでるしかないのかと思ったが、ふと英語が出来ないなりに「is_writable always false」でググったら一番上に出てきた。
selinux... すっかり忘れていた・・・コネクション周りなら思い出せたかもしれなかったが。

# setenforce 0
ついでに、/etc/selinux/config の SELINUX を disabled に変更。
で無事にインストールを続けることができた。

続く...

2011年12月7日水曜日

複数 FLV ファイルから DVD 作成

今回は開発以外で嵌まったことを。
知人に複数 FLV から DVD を作成したいと言われたので調査することに。これが思いのほか嵌まった・・・

そもそも、動画を変換、編集することがかなり久しぶりだった。昔は、DVD-RAM で TV 番組を録画して CM カットして DVD-R に保存なんてこともやっていたが、何年も前であまり覚えていない。
前は、DVD ドライブを買うと、動画編集ソフトやオーサリングソフトがバンドルされていたが、現在手元に何もない・・・なのでフリーソフトでやるしかない。

まず、昔の手順的なものを思い出すことに。たしか、
  1. DVD-RAM(vob たしか中身は mpeg2)に録画
  2. GOP 単位でざっくり CM カット
  3. AVI(huffyuv 可逆圧縮)変換
  4. フレーム単位で細かくカット
  5. mpeg2 に変換
  6. オーサリング
  7. DVD 焼き
みたいなことをやってたはず。途中どっかの手順で音を分離して最後に結合してたような記憶もあるが。
とりあえず、今回は編集が入らないので、
  1. FLV
  2. AVI(huffyuv)に変換
  3. オーサリング(mpeg2 に変換含む)
  4. DVD 焼き
でいけそうだ。

まず、FLV の変換だが、Any Video Converter というソフトでいけそうだ。これで AVI に変換。オーサリングは、Windows7 についてるWindows DVD メーカーを使用した。Windows DVD メーカーは ISO ファイルは作れずに一気に DVD に焼くようだ。
簡単にできたと思い、中身を確認してみると、出た!音ずれだ・・・
そういえば昔も嵌まった・・・だから音を分離して結合してなんて記憶が残ってたわけだ。ちゃんと確認してみると、AVI の時点でずれている・・・先に確認すれば 1 枚無駄にならなかったのに・・・

とりあえず Any Video Converter で変換時に音を分離することにする。で、VirtualDub で結合して AVI の時点で音があってる状態にしてみることに。
ここでさらに問題が。Any Video Converter で作成した AVI(huffyuv) が VirtualDub で開けない。VirtualDub の圧縮の選択肢の中に huffyuv があるというのに。つまりコーデックは入っているということだが。調べてみたら動画再生、作成等の API が 2 種類あるらしい。
  • Video for Windows(コーデックを使用)
  • DirectShow(フィルターを使用)
知っているのは前者のみだったわけで、そういえば ffdshow なるものも入れた気がする。Any Video Converter は両方(?)対応、VirtualDub は前者対応のようだ。
VirtualDub のプラグインで DirectShow を使用するものがあったので入れてみるがうまく認識しなかった。直接 FLV を読み込むプラグインもあるようだったがこれも読み込んでくれない。そもそも、64bit 版の VirtualDub を使っているがプラグインは 32bit 版な気がする。ソース付のもあったのでコンパイルしなおす等もしてみたが、あっているかも分からずやはり認識せず。
仕方ないので、ほかに可逆圧縮はないものかと探したところ、ffv1 とういものが共通で扱えたのでこれでやることに。
で、Any Video Converter で ffv1 を出力後、VirtualDub で読み込み、分離した音を結合した AVI を作成。作成された AVI を見てみると、音がずれている・・・
さらに確認してみると、そもそも、分離した、ffv1 の動画と wav の音の時間がずれている・・・あうわけがない・・・

VirtualDub でどうにかならないかと「オプション」->「音声に同期させる」や「遅れる場合はフレームを落とす」を選択してみたがダメだった。 「音声」->「インターリーブ」あたりを触ってもダメ。
前はどうやっていたか思い出せないが、有料のソフトがいい塩梅でやってくれてたんだろうか。とりあえずさらに調べてみることに。
すると、「映像」->「フレームレート」の「ソースレート調整」->「映像と音声の再生時間が一致するように変更する」という設定があり、これでいけた。

これで映像と音があった AVI ができたので、次は、mpeg2 変換とオーサリングだ。前回みたく失敗するたびに DVD-R が消費されると辛いので、VIDEO_TS 形式なり ISO イメージなりで出力できるアプリケーションを探すことに。mpeg2 に変換できるもの自体が少ないため、選択肢はあまりなく、その中では、メニュー等も作れる DVD forger がよさそうだったのでこれにすることに。

で、またまた問題が。DVD forger は ffv1 形式が読み込めない。かなり振り出しに戻った気分だ。だがここまできてやめるわけにもいかない。すでにかなりの時間を使っている。
Any Video Converter は他の可逆圧縮を選べない。となると、VirtualDub で音の結合をする時点で別形式に変換することに。
可逆圧縮もさほど選択肢がないわけだが、Ut Video Codec YUV が使えたのでこれにする。正直よくわかってないので、ここでも VfW と DirectShow が入り混じっているのかもしれない。

やっと、DVD forger でオーサリングすることに。とりあえずメニューは作らず。DVD forger には音ずれの設定等設定項目があまりないので mpeg2 に変換時に音がずれないでくれと願いつつ、変換 & オーサリングを実行。
確認しみると、おぉ音があってる!後は焼くだけかと、さらっと見てたら動画が途中で終わっている・・・

実は、FLV ファイルは 4 つあって、その 1 つが再生された時点で終わっていた。
ファイルは個々に変換しているので、Ut Video Codec 形式の AVI も 4 つある。それを、DVD forger に追加すると、タイトルが 4 つできる。メニューを作成して、4 つボタンをつけてみると、ボタンクリックからは再生できる。が 1 タイトル終了後メニューに戻ってしまう。次のタイトルが再生できない。見れないことはないのでいいのかも知れないが、美しくない。俺的にアウトだ。
ということで、Ifo Editor なるものを入れて、ifo ファイルを編集することに。
VIDEO_TS.IFO の「VMGM_PGCI_UT」->「LU_1 PGC-Menu_1」の Pre Command や VTS_01_0.IFO の 「VTS_PGCITI」->「VTS_PGC_1」の Pre Command や Post Command をいじってみることに。
(Jump_TT)Jump to Title や(CallSS_VMGM)Call VideoManager PGC など適当にさわってみるが再生されない。メニューにすら飛ばなくなる。PgcEdit のほうがいいという情報も見かけたので入れてみるが変わらない・・・
まったく知識なくいじっているので仕方がないといえば仕方がないが。かと言って IFO の構造を学ぶのも大変そうだ・・・が、もはや意地でやってるので、さらに調べることに。
  • http://www.geocities.jp/montty_jp/backup/index.htm
  • http://dvd.sourceforge.net/dvdinfo/vmi-jmp.html
が、詳しくて参考になった。見てるとどうも、タイトルからタイトルつまり、VTS から VTS には飛べない感じがする。できた VOB ファイルをみると、VTS_01_0.VOB, VTS_02_0.VOB となっていて、VTS_0* の時点で違いがある。これはもしや、VTS_01_0, VTS_01_1 になればいいのかと、DVD forger の設定を見直してみることに。

「Edit videos, audio tracks and subtitles...」から入ったダイアログに「Merge」なるボタンがあるのに気付く。だが押せない。動画を複数選択しても Disable のまま・・・なんのためのボタンだと思いつつ。View のラジオボタンを適当に押していると、「Outline(for re-orderring, merging and deleting titles)」を選択したときに、Enable になった。なんて使いづらいインターフェースだ。View なんて書くと見た目だけ変わるのかと思うじゃね~かと思ったが、よくみりと、ちゃんと書かれている・・・「Outline(for re-orderring, merging and deleting titles)」
英語は苦手だ・・・

とりあえず、4 つ全ての動画を選択して、Merge をクリック。
メニューのボタンが 1 つになったが問題なし。チャプタは?とも思ったが拘りだしてはキリがないし、俺的に拘るところでもないのでスルーすることに。

確認してみるとちゃんと再生された。音が短くそれにあわせた分一番最後が若干さくっと終わる感じはあるが、ご愛嬌ということで。
後は、DeepBurner で DVD に焼いて終了。焼くのはすんなりいった。

久しぶりに動画の編集をやったがやはり大変。昔に比べてマシンスペックはあがっているので、エンコード時間は短いが、それでも数十分、数時間の待ちがあるので、待ったあとダメだった場合が辛い。
まぁ昔は 30 分の動画をエンコードするのに一晩中動かしても終わってなかったりしてたわけだが。

ちなみに著作権が絡む動画は注意が必要。個人的にダウンロードして複製する分には問題なさそうだが、YouTube などはダウンロードの時点で規約違反となる。違法でなければやっていいというわけでもない。モラルの問題もある。
了承を得られている等、著作権的に問題がない動画ならいいが。
本の自炊屋が消えていったりしているので、著作権が絡む動画を今回のように人に頼まれて変換して渡すとなるとアウトな気がする。

長々と書いてて読みにくいことに気付いた。キャプチャ等を貼るべきかと思うがそれもメンドイ。無理やり文字を大きくしたりでなんとかならんかとやってみたが・・・

2011年11月30日水曜日

三角関数と微分積分

前に読んだ OpenCL のサンプルでフーリエ変換が出てきたのでもう少し詳しく知ろうと、
Excelで学ぶフーリエ変換−Excel 2010対応版−
を最近読み始めたのだが、基本知識がなさすぎて最初の時点でつまづいた。
当然、全てが理解できるとは思っていないが、フリーエ変換のの字も出る前の基本知識の説明の時点でつまづいたら先に進みようがないため調べることに。

でてきた式が

ふむふむ、なるほど、なんで?って感じ。

三角関数は、
  • しんこうこうしん
  • ここマイナスしんしん
  • しんたすしんはにしんこう
  • こうたすこうはにこしん
なんて覚えた記憶がある。でどうやって使うの?
公式の導き方も知ってたような記憶があったが、知ってたかもという記憶だけ・・・

まずは三角関数からかと、ググッて勉強。先は長い。Wikipedia に色々公式が載っていた。
まずは、ピタゴラスの定理より

この時点で悩むことになるが・・・
半径 1 の単円で角度 X の場合、x = cosX, y = sinX となり、直角三角形の斜辺の 2 乗は各辺の 2 乗の和になることから上記、式になるようだ。

次は、加法定理。
しんこうこうしん、ここマイナスしんしんは加法定理のようだ。
左辺を覚えてないと意味がなかった。
加法定理の導き方は Wikipedia に載っていた。
A(cos(-α), sin(-α)) B(cosβ, sinβ) の線分の長さから求めるものしか分からなかったが。
線分 AB の長さの 2 乗は、

途中が省かれてて、最初見たときは?だったが、
上記ピタゴラスの定理により、2 に変換されている。
また、sin(-X) = -sinX, cos(-X) = conX による変換も行われる。

次に、+α分回転させた、A'(cos(-α + α), sin(-α + α)) = (1, 0), B'(cos(β + α), sin(β + α)) を考える。
線分 A'B' の長さの 2 乗は、回転させるまえの線分 AB の長さの 2 乗に一致することにより求めるようだ。

さらに、加法定理より積和公式を求める。
  • しんたすしんはにしんこう
  • こうたすこうはにこしん
は、積和公式の変形の和積公式のようだ。
 cos の加法定理、

の2つの式を足して、

が積和公式の一つ。

ここで、α = x, β = x とすると、

となりようやく本題の式に代入可能な形になった。


1/2 は外に出せるはず。で積分だが、+1 の積分は、+x となるのはいいが、問題は cos2x の部分。
cos x であれば、sin x なわけだが・・・
で調べてみると、合成関数の積分なるものを使うっぽい。
t = 2x として、cos t とする。これを t で積分すると sin t。ただこれは t の積分なので
x でやるためには、 t を微分したものを用意して、

で割ってやると

となり、

やっと繋がった・・・
すごい遠回りをしてる気もする。意外とあっさり変換できたりして・・・

2011年11月22日火曜日

ASUS UX31E-RY128 の感想

しばらく使用してみて、(というかほとんど使用していないが・・・)気づいたこと。

タッチパッド
タッチパッドの反応が悪い時がある。いくら触っても反応しない。 いきなり不具合!?または微妙な仕様!?
かとあせったがとりあえずマニュアルを見たところ、キーボード操作中はタッチパッドの反応領域が狭くなるらしい。
つまり、キーボード操作直後は、反応領域が狭いため、一定の部分からタッチしないと反応しない。
 
「コントロールパネル」の「マウス」より設定をみたところ、範囲のサイズと中心点を設定できるようだ。
キーボード入力中にパッドに触るとクリック扱いとなって、別ウィンドウがアクティブになったりしていたので範囲を小さくした。これは便利だ!
ノートパソコンに慣れていないので最近では当然の機能なのかもしれないが・・・

また、タッチパッドの下に、左クリック、右クリック用のボタンが 2 つあるが、これを使わずともタッチパッドのジェスチャーで右クリックやドラッグ、スクロール、ズーム等の処理ができる。タッチパネルの影響なんだろうか。

キーボード
キーボードの操作感だが、普段メカニカルな感じが好きなため、ノートのキーボードはあまり好きではないが、ノートにしては結構クリック感があるほうだと思う。悪くないかと。

重量
持ち歩いた感じ、やはり本などと一緒に持ち運ぶと重い・・・クッション入りのバッグも欲しいが、それだけで 1kg とかするので迷い中。壊れては意味がないがデフォルトのケースはあるので。
電車で座れずに立ったままブラウジング等もやってみたが、立ちながらやるには大きい。腕も疲れる。
さすがにタブレットのようにはいかなかった。座れる場合は問題ないが。

解像度
解像度は結構満足できるレベル。ブラウジングやちょっとした入力なら何の問題もない。
この記事もノートでやっているがいい感じ。


現時点では、こんなもんか。もうちょっと使ってみれば色々でるかもしれないが。


ノートより通勤途中の地下鉄で WiMax が繋がらないのが痛い。駅停車時ぐらい繋がるのかと思ってたのが甘かった・・・

2011年11月14日月曜日

Jericho HTML で一部サイトが文字化け

前回のソースで一部サイトが文字化けを起こした。

Souce のコンストラクタに URLを渡した場合は、ヘッダー情報の Content-Type の charset からエンコードが取得できるかもだが(Jericho が取得しているかは未調査)、BODY 部分のストリームを渡す場合、取得出来ないため内容から自動判別すようで、そこがおかしくなっているようだった。
なので指定してやることに、
HttpClient http = new DefaultHttpClient();
HttpResponse res = http.execute(new HttpGet(URI.create("http://www.example.com")));
if (res.getStatusLine().getStatusCode() != HttpStatus.SC_OK)
{
  LOG.error("Failed to load uri.");
  return false;
}    

InputStream in = res.getEntity().getContent();
if (res.getHeaders("Content-Encoding").length > 0 &&
  "gzip".equals(res.getHeaders("Content-Encoding")[0].getValue()))
  in = new GZIPInputStream(in);

String charset = EntityUtils.getContentCharSet(res.getEntity());

Source source = null;
if (charset != null) source = new Source(new InputStreamReader(in, charset));
else source = new Source(in);
14 行目で Content-Type の charset からエンコードを取得して、指定があれば、17 行明で明示的に指定してやることに。直接渡しているので、Shift_JIS 等で部分的に文字化けがおきそうだがとりあえず。

Source(final Reader reader) の実装が、
this(reader,(reader instanceof InputStreamReader) ? ((InputStreamReader)reader).getEncoding() : null);
となっていて、instanceof が気に入らない。Source(final Reader reader, final String encoding) が public だといいのだが。

Content-Type の charset がなければ今まで通り自動判別。

もっとスマートにいかないものか・・・

2011年11月11日金曜日

Shell から rsync

しょうもないことで嵌まったこと。

rsync を実行してバックアップする Shell ファイルを作成中のこと。exlude で除外ファイルを指定したかったわけだが・・・
CMD="rsync -avz"
echo CMD "--exclude='*.pid'" src1 dest1
echo CMD"--exclude='*.lock" src2 dest2
上記の様に普段は、まずコマンドの前に echo をつけてコマンド、引数の確認後、出力されたコマンドをコピペして実行し動作確認を取った後 echo を外して Shell の確認って手順で作成することが多い。
今回、コピペでやると --exclude で指定しているファイルが除外されるが、Shell ファイルを実行すると除外されなかった。

原因は、--exclude オプションがクウォートで囲まれてコマンドに渡されているためで、当然なわけだが、echo で出力されると文字列が展開されてクウォートが表示されない。

実際は他にもオプションや変数を渡してたりして、気づくのに結構かかってしまった。

2011年11月9日水曜日

Scala の勉強(インストール)

前にちょっと調べた程度で終わっていた Scala を勉強しなおそうかと思う今日この頃。
はっきり言って全然覚えてないので初歩からスタートすることに。

まずは環境を作るところからか。(いつものように Cygwin 上でやってみる)
  1. http://www.scala-lang.org/ の Download Scala より Windows の最新版 scala-2.9.1.final.zip をダウンロード。
  2. インストール場所へ展開。
  3. 環境変数 SCALA_HOME と PATH を設定。
とりあえずこんな感じか。

emacs 用に scala-mode も付属している。さらに ENSIME なるものもあるようなので入れてみる。
  1. ${SCALA_HOME}/misc/scala-tool-support/emacs へ移動。
  2. make ELISP_COMMAND=emacs のパス
  3. https://github.com/aemoncannon/ensime/downloads より ENSIME をダウンロード。
  4. インストール場所へ展開。
  5. .emacs あたりに設定。(yasnippet も使用)
    (when (require 'scala-mode-auto nil t)
      (add-hook 'scala-mode-hook
                '(lambda ()
                   (yas/minor-mode-on)))
      (when (require 'ensime nil t)
     (add-hook 'scala-mode-hook 'ensime-scala-mode-hook))
      )
    
eclipse プラグインも入れておきたいがこれはそのうち。

参考にするサイトとして、
あたりを調べつつやっていこうかと。
は初心者向けらしい。英語なんで少しずつだがここからやってみるか。

2011年11月3日木曜日

ノート PC 購入

やっぱりノート PC を購入。
ネットブックを買うならタブレットでもいいかと思ったが、もう少しディスプレイ等のスペックも欲しかったので、ウルトラブックなるレベルのものにしたいと。
Mac Book Air で Mac デビューするのもありかと思ったけど、結局調べてた ASUS UX31E-RY128 を買ってしまった。
とりあえず触ってみてから決めようと、発売日の今日秋葉原に行ってきた。Sofmap で展示されているのを見つけとりあえず触って見ることに。韓国版(?)が展示されていて、キーボードが違っていた。英語キーボードが良かったが、発売されているのは日本語キーボードだけだということ。
タブレットに比べるとさすがに重さは感じるが、持ち運びは楽そうな感じだった。SSD256GB 版は発売がまだだった。まぁ 128GB もあれば十分かなと。

Sofmap ヨドバシ と見て、最終的にヤマダ電機で購入。
他の店より 3000円ほど安く、WiMAX の 1 年契約でさらに 5000円引きと。WiMAX の割引はヨドバシもやってそうだったが。
カード払いだとポイント 8% になるということで、悩んでたら 10% にしてくれるということで購入することにした。

 ケースがデフォルトで付いてるのが良い。

こちらは WiMAX ルータ。
部屋での電波は怪しいかなと思ったが、電波 は 2 本立った。
家には無線ルータもスイッチもないので直接ネットに繋がるのはいいかも。

2011年11月2日水曜日

Jericho HTML で Content-Encoding が gzip なサイトのパース

Jericho HTML でパースできないサイトがあるようで、調べてみると、Content-Encoding が gzip になっていた。
元ソース。
Source source = new Source(new URL("http://www.example.com"));

Accept-Encoding からはずせばいいのかもしれないが、HttpClient も使用しているため、そちらで対応することに。
HttpClient http = new DefaultHttpClient();
HttpResponse res = http.execute(new HttpGet(URI.create("http://www.example.com")));
if (res.getStatusLine().getStatusCode() != HttpStatus.SC_OK)
{
  LOG.error("Failed to load uri.");
  return false;
}    

InputStream in = res.getEntity().getContent();
if (res.getHeaders("Content-Encoding").length > 0 &&
  "gzip".equals(res.getHeaders("Content-Encoding")[0].getValue()))
  in = new GZIPInputStream(in);
Source source = new Source(in);
Jericho HTML だけで対処出来る方法があればいいのだが。
compress, deflate は未対応・・・

文字化けしたので、続き

2011年10月31日月曜日

ノートPC || タブレット

ノート PC またはタブレットを買おうか迷い中。
携帯はガラケーで、モバイル系一切持ってないので、何かしら欲しいかなと。
携帯で Web を見ることもなく、まったく不便を感じてないんでいらないっちゃいらないんだが・・・

勉強会とか参加したことないので、ちょっと参加してみたいなと。
で参加するならタブレットかノート PC かなと。
開発環境入れれるノート PC のほうが良さげだが。
通信に、WiMAX なりイーモバイルなりが必要になるけど。

ノートならMac Book Air サイズのやつがいい。持ち運びは軽いほうがいい。
ただ、慣れないだけかもしれないがあまり Mac が好きになれない。

11/3 に発売する、ASUS ZENBOOK が結構よさげ。
ディスプレイは、13.3 型がいいかな。ディスクは 128GB で十分な気がする。
なので UX31E-RY128

キーボードが日本語なのが問題だが・・・
売ることがあるとすれば日本語キーボードのほうがいいな。
まぁのどかとかでキーバインド変えちゃうのもありか。
のどかのライセンスも持ってないわけだが。

とりあえず実物触ってから考えよう。

ここまで迷ってると何かしら買うんだろうな・・・

2011年10月28日金曜日

オーバーライド時のアクセス修飾子変更 C++ 編

PHP 編Java 編C# 編に続き、 C++ でも検証。C++ は好きだがこれも慣れていないため、怪しいかも・・・

まず、親クラス。
class ParentClass
{
private:
  virtual void func1() { std::cout << "Parent private func1" << std::endl; }
protected:
  virtual void func2() { std::cout << "Parent protected func2" << std::endl; }
public:
  virtual void func3() { std::cout << "Parent public func3" << std::endl; }
 
public:
  virtual ~ParentClass() {}
  virtual void call()
  {
    func1();
    func2();
    func3();
  }
};
private, protected, public の 3 種類のメソッドと、それらを呼び出すメソッドを作成。

子クラス1 は public に変更。
class Child1Class : public ParentClass
{
public:
  virtual void func1() { std::cout << "Child1 private -> public func1" << std::endl; }
  virtual void func2() { std::cout << "Child1 protected -> public func2" << std::endl; }
  virtual void func3() { std::cout << "Child1 public func3" << std::endl; }
  virtual ~Child1Class() {}
};
シンタックスエラーは起きない。

子クラス2 は protected に変更。
class Child2Class : public ParentClass
{
protected:
  virtual void func1() { std::cout << "Child2 private -> protected func1" << std::endl; }
  virtual void func2() { std::cout << "Child2 protected func2" << std::endl; }
  virtual void func3() { std::cout << "Child2 protected -> protected func3" << std::endl; }
public:
  virtual ~Child2Class() {}
};
これもシンタックスエラーは起きない。

子クラス3 は private に変更。
class Child3Class : public ParentClass
{
private:
  virtual void func1() { std::cout << "Child3 private func1" << std::endl; }
  virtual void func2() { std::cout << "Child3 protected -> private func2" << std::endl; }
  virtual void func3() { std::cout << "Child3 public -> private func3" << std::endl; }
public:
  virtual ~Child3Class() {}
};
これもシンタックスエラーは起きない。

実行してみると、
ParentClass* p = new ParentClass();
p->call();
std::cout << "----------" << std::endl;
delete p;

Child1Class* c1 = new Child1Class();
c1->call();
std::cout << "----------" << std::endl;
delete c1;

Child2Class* c2 = new Child2Class();
c2->call();
std::cout << "----------" << std::endl;
delete c2;

Child3Class* c3 = new Child3Class();
c3->call();
delete c3;
結果は、
Parent private func1
Parent protected func2
Parent public func3
----------
Child1 private -> public func1
Child1 protected -> public func2
Child1 public func3
----------
Child2 private -> protected func1
Child2 protected func2
Child2 protected -> protected func3
----------
Child3 private func1
Child3 protected -> private func2
Child3 public -> private func3

全てのパターンで特に制限なく変更出来ている。
Java とかと逆の制限があったような気がするが、気のせいだったか。

何か間違っている可能性も・・・

Cygwin g++ (GCC) 4.5.3
Visual C++ 2010
でコンパイル。 いくつかの言語で試してみたものの、結果まぁ言語仕様書を読めよということで。

2011年10月24日月曜日

オーバーライド時のアクセス修飾子変更 C# 編

PHP 編Java 編に続き、 C# でも検証。C# は慣れていないため、怪しいかも・・・

まず、親クラス。
class ParentClass
{
  // 仮想または抽象メンバーには、private を指定できません。
  private /* virtual */ void func1() { Console.WriteLine("Parent private func1"); }
  protected virtual void func2() { Console.WriteLine("Parent protected func2"); }
  public virtual void func3() { Console.WriteLine("Parent public func3"); }

  public virtual void call()
  {
    this.func1();
    this.func2();
    this.func3();
  }
}

private, protected, public の 3 種類のメソッドと、それらを呼び出すメソッドを作成。
他と違い、この時点でエラーが発生。仮想関数を private にできないらしい。

子クラス1 は public に変更。
class Child1Class : ParentClass
{
  // オーバーライドする適切なメソッドが見つかりませんでした。
  public /* override */ void func1() { Console.WriteLine("Child1 private -> public func1"); }
  // 'protected' 継承メンバー 'ConsoleApplication1.ParentClass.func2()' をオーバーライドするときに、アクセス修飾子を変更できません。
  public /* override */ new void func2() { Console.WriteLine("Child1 protected -> public func2"); }
  public override void func3() { Console.WriteLine("Child1 public func3"); }
}

func1 は親クラスを virtual 宣言していないためオーバーライド出来ず、コンパイルエラーとなる。
func2 はアクセス修飾子が変更できない旨のエラーがでる。PHP や Java と違い緩い方向にも変更できない。
func1, func2 共に override を外すと、コンパイルは通る。
func2 は override を外しただけでは、override か new を付けろと警告が出る。

子クラス2 は protected に変更。
class Child2Class : ParentClass
{
  // オーバーライドする適切なメソッドが見つかりませんでした。
  protected /* override */ void func1() { Console.WriteLine("Child2 private -> protected func1"); }
  protected override void func2() { Console.WriteLine("Child2 protected func2"); }
  // 'public' 継承メンバー 'ConsoleApplication1.ParentClass.func3()' をオーバーライドするときに、アクセス修飾子を変更できません。
  protected /* override */ new void func3() { Console.WriteLine("Child2 public -> protected func3"); }
}

func1 は同じようにエラー。
func3 はアクセス修飾子の変更によるエラー。

子クラス3 は private に変更。
class Child3Class : ParentClass
{
  // 仮想または抽象メンバーには、private を指定できません。
  private /* override */ void func1() { Console.WriteLine("Child3 private func1"); }
  // 仮想または抽象メンバーには、private を指定できません。
  private /* override */ new void func2() { Console.WriteLine("Child3 protected -> private func2"); }
  // 仮想または抽象メンバーには、private を指定できません。
  private /* override */ new void func3() { Console.WriteLine("Child3 public -> private func3"); }
}

func1 は同じようにエラー。
func2, func3 もアクセス修飾子によるエラーとなる。

実行してみると、
ParentClass p = new ParentClass();
p.call();
Console.WriteLine("----------");
Child1Class c1 = new Child1Class();
c1.call();
Console.WriteLine("----------");
Child2Class c2 = new Child2Class();
c2.call();
Console.WriteLine("----------");
Child3Class c3 = new Child3Class();
c3.call();

結果は、
Parent private func1
Parent protected func2
Parent public func3
----------
Parent private func1
Parent protected func2
Child1 public func3
----------
Parent private func1
Child2 protected func2
Parent public func3
----------
Parent private func1
Parent protected func2
Parent public func3

ほとんどオーバーライド出来ないため、PHP や Java とは異なる結果になった。

private, public -> protected -> private 方向は勿論、protected -> public の変更もできないようだ。

2011年10月23日日曜日

オーバーライド時のアクセス修飾子変更 Java 編

PHP 編 に続き、今度は Java で検証。

まず、親クラス。
class ParentClass
{
  private void func1() { System.out.println("Parent private func1"); }
  protected void func2() { System.out.println("Parent protected func2"); }
  public void func3() { System.out.println("Parent public func3"); }

  public void call()
  {
    this.func1();
    this.func2();
    this.func3();
  }
}
private, protected, public の 3 種類のメソッドと、それらを呼び出すメソッドを作成。

子クラス1 は public に変更。
class Child1Class extends ParentClass
{
  // メソッドはスーパータイプのメソッドをオーバーライドまたは実装しません
  // @Override
  public void func1() { System.out.println("Child1 private -> public func1"); }
  @Override
  public void func2() { System.out.println("Child1 protected -> public func2"); }
  @Override
  public void func3() { System.out.println("Child1 public func3"); }
}
func1 は private メソッドをオーバーライド出来ないため、コンパイルエラーとなる。
@Override アノテーションを外すと、コンパイルは通る。

子クラス2 は protected に変更。
class Child2Class extends ParentClass
{
  // メソッドはスーパータイプのメソッドをオーバーライドまたは実装しません
  // @Override
  protected void func1() { System.out.println("Child2 private -> protected func1"); }
  @Override
  protected void func2() { System.out.println("Child2 protected func2"); }
  // Child2Class の func3() は ParentClass の func3() をオーバーライドできません。スーパークラスでの定義(public) より弱いアクセス特権を割り当てようとしました。
  // @Override
  // protected void func3() { System.out.println("Child2 public -> protected func3"); }
}
func1 は同じようにエラー。
func3 は PHP と同じように、public -> private への変更でエラーとなる。func1 とは異なり、アノテーションを外しただけではエラー。定義自体を削除。

子クラス3 は private に変更。
aclass Child3Class extends ParentClass
{
  // メソッドはスーパータイプのメソッドをオーバーライドまたは実装しません
  // @Override
  private void func1() { System.out.println("Child3 private func1"); }
  // Child3Class の func2() は ParentClass の func2() をオーバーライドできません。スーパークラスでの定義(protected) より弱いアクセス特権を割り当てようとしました。
  // @Override
  // private void func2() { System.out.println("Child3 protected -> private func2"); }
  // Child3Class の func3() は ParentClass の func3() をオーバーライドできません。スーパークラスでの定義(public) より弱いアクセス特権を割り当てようとしました。
  // @Override
  // private void func3() { System.out.println("Child3 public -> private func3"); }
}

func1 は同じようにエラー。
func2, func3 でエラーとなる。やはり、厳しい方向への変更はできないようだ。

実行してみると、
ParentClass p = new ParentClass();
p.call();
System.out.println("----------");
Child1Class c1 = new Child1Class();
c1.call();
System.out.println("----------");
Child2Class c2 = new Child2Class();
c2.call();
System.out.println("----------");
Child3Class c3 = new Child3Class();
c3.call();

結果は、
Parent private func1
Parent protected func2
Parent public func3
----------
Parent private func1
Child1 protected -> public func2
Child1 public func3
----------
Parent private func1
Child2 protected func2
Parent public func3
----------
Parent private func1
Parent protected func2
Parent public func3

エラー部分を削除したソース、結果共に、PHP と同じようになった。

protected -> public への変更はできるが、public -> protected -> private への変更はできない。
private はオーバーライドできない。

余談だが、コンパイルエラーとなるのはやはりいい。

2011年10月21日金曜日

オーバーライド時のアクセス修飾子変更 PHP 編

オーバーライド時にアクセス修飾子の変更を検証。

まず、親クラス。
class ParentClass
{
  private function func1() { echo "Parent private func1\n"; }
  protected function func2() { echo "Parent protected func2\n"; }
  public function func3() { echo "Parent public func3\n"; }

  public function call()
  {
    $this->func1();
    $this->func2();
    $this->func3();
  }
}
private, protected, public の 3 種類のメソッドと、それらを呼び出すメソッドを作成。

子クラス1 は public に変更。
class Child1Class extends ParentClass
{
  public function func1() { echo "Child1 private -> public func1\n"; }
  public function func2() { echo "Child1 protected -> public func2\n"; }
  public function func3() { echo "Child1 public func3\n"; }
}
シンタックスエラーは起きない。

子クラス2 は protected に変更。
class Child2Class extends ParentClass
{
  protected function func1() { echo "Child2 private -> protected func1\n"; }
  protected function func2() { echo "Child2 protected func2\n"; }
  // Access level to Child2Class::func3() must be public (as in class ParentClass)
  // protected function func3() { echo "Child2 protected -> protected func3\n"; }
}
func3 の変更でエラーとなる。public を protected に変更できないようだ。

子クラス3 は private に変更。
class Child3Class extends ParentClass
{
  private function func1() { echo "Child3 private func1\n"; }
  // Access level to Child3Class::func2() must be protected (as in class ParentClass)
  // private function func2() { echo "Child3 protected -> private func2\n"; }
  // Access level to Child3Class::func3() must be public (as in class ParentClass)
  // private function func3() { echo "Child3 public -> private func3\n"; }
}
func2, func3 でエラーとなる。やはり、厳しい方向への変更はできないようだ。

実行してみると、
$p = new ParentClass();
$p->call();
echo "----------\n";
$c1 = new Child1Class();
$c1->call();
echo "----------\n";
$c2 = new Child2Class();
$c2->call();
echo "----------\n";
$c3 = new Child3Class();
$c3->call();
 
結果は、
Parent private func1
Parent protected func2
Parent public func3
----------
Parent private func1
Child1 protected -> public func2
Child1 public func3
----------
Parent private func1
Child2 protected func2
Parent public func3
----------
Parent private func1
Parent protected func2
Parent public func3

親クラスは当然の結果が出ている。
子クラス1の func1 は、親クラスの func1 が private なためオーバーライドできずに、親クラスの func1 が呼ばれている。
子クラス2の func1 も同様。func2, func3 はオーバーライドしていないためそのまま親クラスのものが呼ばれている。
それぞれの子クラスで、call を再定義してやると、それぞれの func1 が呼ばれる。

protected -> public への変更はできるが、public -> protected -> private への変更はできない。
private はオーバーライドできない。

歯!?

歯が抜けた








実は、インプラントのかぶせ物。
仮付けして、もうかれこれ 1 年半。
過去に本付けして 2 度ほど割れてしまったので、今回長めに様子を見ることになってた。
そろそろ様子見も終わりで衛生士さんに見てもらったら本付けしようという段階だったわけだが。

通ってる歯医者は、夜21時ぐらいまでやってて土日もやってるので結構人気で予約が取れない。
3 ヶ月に 1 回定期健診の葉書がくるんだがそこから予約が 1 ヶ月になるので結果、 4 ヶ月検診になってしまっている。

外れたのですぐに電話したら、1週間後なら予約が取れると。正確には無理やりねじ込むからすごい待つことになるらしい・・・
痛みがあるわけでもないので、緊急性は低いしまぁ仕方ないか。

2011年10月20日木曜日

org-mode の HTML エクスポートの文字コード

さっそくはまったエピソードを。

普段、Windows 上での作業なので、文字コードの設定は japanese-shift-jis-dos にしているんだけど、org-mode で書いたものを HTML にエクスポートするので、UTF-8 がいいかなと思い、変更方法を調査。

とりあえず、ファイルの文字コードを UTF-8 にしてエクスポート。(C-x Enter f)
なぜか文字化け。meta タグ等の charset は変わるものの、文字コードは Shift_JIS のまま。
次に、それぽい変数 org-export-html-coding-system を発見したので設定してみた。*scratch* にて
(setq org-export-html-coding-system 'utf-8)
そしてエクスポートするが同じ症状。
なぜだということで、elisp は全く詳しくないがソースを見てみることに。とりあえず
M-x describe-variable org-export-html-coding-system
から開始。すると、org-html.el でそれっぽいところが。
(coding-system (and (boundp 'buffer-file-coding-system)
            buffer-file-coding-system))
(coding-system-for-write (or org-export-html-coding-system
                 coding-system))
(save-buffer-coding-system (or org-export-html-coding-system
               coding-system))
(charset (and coding-system-for-write
          (fboundp 'coding-system-get)
          (coding-system-get coding-system-for-write
                 'mime-charset)))
org-export-html-coding-systemは nil のままだと、バッファの文字コードで決まるようにみえる。
最初のアプローチであってるように見えたが・・・
再起動等やってやり直してみるもやはり同じ症状。
M-x describe-coding-system すると utf-8 になってるように見える。

色々ググッてみると、emacs 23.3 では日本語処理あたりに不具合があるとか。
Magic Comment でいけたというのを見かけたのでつけてみた。
# -*- coding: utf-8 -*-
するとうまくいくものといかないものと。
キャッシュされてるのか日付みたりしてるのかなんなのか、出力されないものがような。何度かやってたら、全て UTF-8 になったので釈然としないがこれでよしということに。

で、家帰ってこれ書くために同じ事やってみたら、最初のアプローチでいける・・・
org-export-html-coding-system の設定でもいける・・・

何か勘違いしてたのか、会社の設定と違うところがあるのか不明・・・
とりあえず、Magic Commentは付けたままの方向に。

2011年10月19日水曜日

ブログ開始

、初めてのブログ作成。

祝うべき日です。初めてなので何を書いていいのかわからないけど・・・ 。

タイトルにあるように、日々学んだことなんかを書いていこうかなと。

技術的なメモはこれまで、Wiki に書いてたんだけど使い勝手がイマイチなので、 org-mode で保存しようかと移行中。

色々あって週末ぐらいしか繋がらないけど、
http://technicalknowledge.moe.hm/
にエクスポートしてアップしてるとこ。
なので技術的というより、しょうもないことではまったこととか、日々の日記が主になるかも。


特に趣味も無いので書くことがあまりなさそうだけど、ぼちぼち続けていければいいかな。