JavaScriptをノンプログラマに教えるMEMO

まだまったくもってメモレベル。方針とか気づいたこととかごちゃ混ぜ。

jQuery前提

とりあえず jQuery 前提で。宗教戦争には興味なし。小さく十分なことができ情報が豊富、と三拍子揃ったライブラリはそれほどない。

アプリケーションを書きたいプログラマは自分の好きなものを選べばよい。

JavaScriptの記述位置

JavaScript(以下、JSと略記)

  1. 外部ファイルに書く
  2. 基本的には HTML の </body> の上で読む
  3. こうやって書く
jQuery( function($) {
  ...
});

1, 2 は比較的簡単に説明できるが 3 は面倒なので端折る。突っ込んでくる人がいてもその人の理解のレベルを見て判断する。

JSの記述位置と実行タイミング

理解する気と力のある人には説明する。

  • 基本的に JS は書いた位置でそのまま実行される
  • function で囲めば呼び出されたタイミングで実行される
  • jQuery( function($) {} ); で囲むと HTML が組み上がってから実行され、かつ他のライブラリを利用するパーツと組み合わせても安全
  • HTML の上の方に書くと HTML の読み込み前に JS の解釈が走って「見た目」の出来上がりが遅くなるので下に書く

JS の実行が遅れることによる「見た目の変化」が気になる場合は上に置いて一工夫することになるが、それは応用編にしておく。

Firebugとconsole.log

alert() は捨てる。

  • Firebug をすでに使っていることが前提
  • コンソールってあるよ
    • ここで実行もできるよ
  • JS の中で console と書くとこの「コンソール」を意味するよ。そこに log() でメッセージを書けるよ。

最初しつこいくらい console.log() を書いて確認してもらう。コンソール直叩きはそのあとで。ある程度コードが長く(と言っても10行くらいでいいんだけど)なってきた際に console.log が自然に出てこないと困る。

セレクタセレクタセレクタ

セレクタの知識不足は致命的。セレクタをセレクタとして認識できないとセレクタをクォートで囲んで与えるという説明も通じない。

「何を」「どうする」の「何を」がないと始まらない。

CSS 3 セレクタの知識も大事。この知識の足りないプログラマは無駄な処理を自分で作り込み始めてしまう。ここはノンプログラマ側から攻めてやるべき。「書かずに実現する」ことが「書いて実現する」ことより重要。

オブジェクト.メソッド()

メソッドの前の . を忘れたり後ろの ( ) を忘れたりする。とにかく型で覚える。

オブジェクト.メソッド()

これが分かればコードのかなりの部分の「型」が分かるはず。

文字列

ノンプログラマは地の文と文字列の区別がつかない。だからコードのパーツを捉えられるようにサポートする。これはオブジェクトの名前、これはメソッド、ここからここまでが引数。

コードのいわば「品詞」が分かるまではそれなりに時間が掛かる。短めのコードをたくさん読んで動きを理解するのが大切。

引数

  • ( ) の中に何を与えるのかはメソッド次第
  • メソッド( ) のリファレンスを読まないと分からない。読め。絶対。

ここら辺は比較的覚えればいい HTML や CSS とは異なる。リファレンスをざっくり理解し、いつでも引けるようにしておく、ちゃんと補完される環境を知るなどの努力が必要。

リファレンスはカタマリで読め

とりあえず

  • Attributes
  • CSS
  • Effect
  • Event
  • Selectors

その後

  • Manipulation
  • Utilities の .each()

くらいかなぁ。

メソッド名だけで調べて完結してしまうのではなく、カタマリで「読む」と「掴めてくる」はず。

リファレンスの記法が分からなければ分かりそうな人をつかまえて聞く。聞ける人がいなくてもいっぱい読んでると結構分かってくる。

CSSとの組み合わせ

JSの中でHTMLの要素を自動で作られるとCSSが当たらないけどどうしたらいいの?

という話。公開されているスクリプトを設置してそのデザインをカスタマイズする、というのはかなりよくある話だと思う。

まずは要素の特定

  • ドキュメントを読む
    • 書いてないのはクソ。できるだけ採用しない。
  • どのような要素が存在しているかを inspect できること
  • inspect しても分からない場合は jQuery plugin なら jQuery のリファレンスの manipulation のメソッド呼び出しを探す
    • そこできっと何かが起きている

リファレンス重要。

スタイルを書く

  • とりあえず jQuery.css() で書いちゃう
    • 何に対してスタイルを当てればよいのかを知るにはこれが早い
  • できるだけ外部 CSS の important! でやってみる
  • Stylish を併用するといいかも

CSS はやはり独立した CSS ファイルの中にあった方がエラーチェックもちゃんと機能するしメンテしやすい。

小さい課題からやる、何度も同じ課題をやる

  • いきなり何行もコードを書かなきゃいけないことに興味を持つとハードルが高い

短いといってもまったく読めない状態での数行は読める人の100行くらいに相当するかもしれない。

  • 何度も同じ課題をやる

さすがにまったく同じではない方がよい。自分でちょっとだけ違うバージョンを想定してそれをいくつも練習する。そうやって記法やリズムを自分の身体に染み込ませる。他の人は知らないけど自分は「書く」行為にはリズムが大切だと思っている。コードはただの字面じゃない。

コメント

基本は CSS と同じにしておくといいかも。

/*
  ...
*/

ただ

//

以降行末までという形もあるので、見てもビックリしない。

参考

Exif って意外にメンドイ

※ そろそろこの「メンドイ」「面倒くさい」シリーズのタイトルも飽きてきたな。

singapore で Web アルバム作ってますよというか singapore 配下のディレクトリに写真のデータ放り込んでおく1と楽でいいなという話は以前書いた通りなんだけども、メタデータ(metadata.ja.csv)の作成がやっぱり面倒くさい。

以前は写真を放り込んだディレクトリで emacs を開いて M-x shell から ls して写真の一覧を作成して、それでチマチマコピペしながら必要なフィールド数の分カンマを打ったり、適切なフィールドにデータを入力したりしてたんだけど、案の定激しく面倒くさい。

ということでコッソリと、指定ディレクトリ内の JPEG ファイルの Exif データを読み取って、設定ファイルに従って singapore 用の csv ファイルを作成するツールを作ってみていた。動くようになってからおぉ割と便利だこれは、と気づくまで時間は掛からなかったんだけど、今回は作る段階で以下の点にハマった。

exif を読み取る ruby 用のライブラリがあんまり充実してない

どうせなら露出補正の値がほしいと思った2んだけど、なんかあんまりみんなそこまで踏み込んでくれない。個人的にはコマンドラインでも使いやすく、情報量の豊富な exiv2 が気に入ってるんだけど、libexiv2-ruby は FreeBSD 上でうまく gem install できなかった。

ぼくちんバインディングの作成なんてできないので諦めて今回は exiv2 の実行バイナリを叩くことにした。うーんかっこ悪いけどしゃあないか。サーバは速くなったことだし、いつも動かすものではないので負荷も気にしないこととする。

カメラによって入ってるタグが違う

なんか独自タグがあるぞ…。どこの業界もこういう標準フォーマットってある程度までしか守られないんだよな。まったくもう。

あと似たような意味の値が2つあることに気がついた。

タグ意味タグ意味
ExposureTime露光時間FNumberF値
ShutterSpeedValueシャッタスピードApertureValue絞り値

どうもそれぞれ下の値の方が正確っぽい。上の値は代表的な値に丸められてしまっているらしい。

が。手元の Nikon のカメラの場合は ShutterSpeedValue は存在しない代わりに ExposureTime の方に中途半端な値が入っている。これはたぶん他の機種の ShutterSpeedValue に相当してるんじゃないかろうか? うーむ、ということは下の値を優先的に取得するようにして、なかったら上の値を取る、っつー動きにしないといかんのか。対応した。

sort オプションの存在に気づく

なんつーか、今までお前は何をしていたんだという感じだけど、singapore.ini にギャラリー(フォルダに相当)のソート、写真のソートについての設定項目を発見! そうか、なんか今までファイル名の順番でしか写真が一覧できなくて不便だなと思っていた(複数台のカメラがある場合にちゃんと時系列に並んでくれない)んだけど、ちゃんと設定項目あるんだね。

あ、そうかこれは date フィールドの値を読み取ってソートするオプションなのか。こんなの手で入力するなんて狂気の沙汰だからファイル名のソートに設定していたのかもしんない。ということはツールで自動作成するようにした今はちゃんと時系列表示にできるではないか! 設定変更、リロード! おぉ! ちゃんと時系列に出てくるじゃん!

さて、metadata.ja.csv の方にもうちょっと詳細なデータを記入…しようと思ったらこっちはファイル名の順番のままだから singapore 上の順番と完全に食い違っちゃって編集しにくい。

うぇ。ということは metadata.ja.csv を作成する段階でも日時順とかでソートする機能があった方がいいんだな…。うーん。できなくはないんだが、ちょっと面倒くさくなってきたな。また今度考えよう。

できた。というか実はソートの機能は一度付けたけど singapore 上で効果がなかったので殺しておいたのだった。ちゃんと使えるように optparse とかあれこれ調整しておしまい。ついでに reverse sort もできるようにしておいた。

  1. 接続は WebDAV にしたので Web サーバと PHP 以外に必要なものがないのもステキ 

  2. なぜか今のカメラに変えて以来、やたらと露出補正するようになった。どうも auto の露出が好みに合わないらしい。 

PukiWiki の Namazu 検索の精度を多少上げる

http://pukiwiki.sourceforge.jp/?PukiWiki%2FNamazu

に上げたのですが、一応こっちにも貼っておきます。pukiwiki.pl をいじって、pukifile.pl として作成しました。合わせて mime type も text/pukifile にしときました。PukiWiki フォーマットのパースはとりあえず Namazu のデフォルトの重み付けの設定で有効になっているタグだけ見てます。それ以外は HTML にすらなりません。

[2005-11-11 追記]案の定というか pukiwiki.org の混乱後、添付ファイルがなくなってました。こっちにも貼っておいてよかった。あと、EUC のファイルしか考えてないので、PukiWiki を utf-8 で運用している場合は 検索結果の画面でページ名が化ける可能性があります。mknmz のプロセス自身を LANG=ja_JP.UTF-8 の環境で動かせばひょっとしてうまくいかねーかなとか思ったりもするんですが、自分では utf-8 での運用は一切していないのでよく分かりません。

スクリプトでの対応としては要するに pack のところをいじるってことになるはずです。$file と、そのファイルの中身のコードが一致するようにごにょってやれば ok のはず。

package pukifile;
use strict;
require 'html.pl';

sub mediatype() { return ('text/pukifile'); }
sub status() { return 'yes'; }
sub recursive() { return 0; }
sub pre_codeconv() { return 1; }
sub post_codeconv () { return 0; }
sub add_magic ($) { return; }
sub filter ($$$$$) {
    my ($orig_cfile, $cont, $weighted_str, $headings, $fields) = @_;
    my $cfile = defined $orig_cfile ? $$orig_cfile : '';

    util::vprint("Processing pukiwiki file ...\n");

    my ($path,$file,$ext) = $cfile =~ m#^(.*/)(.*)(\.txt)$#;

    $file = pack("H*",$file);
    $file =~ s/[\[\]]//g;
    my( $title ) = $file;
    $file =~ s/(\W)/'%'.unpack("H2",$1)/eg;
    $fields->{'uri'} = "$path$file";

        $$cont = "<h1>".$title."</h1>\n" . $$cont;
        puki_filter( $cont );

        html::html_filter( $cont, $weighted_str, $fields, $headings );
        gfilter::line_adjust_filter($cont);
        gfilter::line_adjust_filter($weighted_str);
        gfilter::white_space_adjust_filter($cont);
        $fields->{'title'} = $title;

    return undef;
}

sub puki_filter(*) {
    my( $cont ) = @_;

    # 改行で配列に分割(gfilter のツールでは white space が落ちるからダメ)
    $$cont =~ s/\r\n?/\n/g;
    my( @body ) = split( /\n/, $$cont );

    # PukiWiki フォーマットのつもりで簡易パース
    my( $line );
    foreach $line ( @body ) {
        chomp( $line );
        my( $level ) = 0;
        # Heading
        if ( $line =~ s/^(\*+)// ) {
            $level = length( $1 ) + 1;
        }
        # comment
        if ( $line =~ s/^\/\/// ) {
            $line = "<!-- " . $line . " -->";
        }
        # anchor と emphasis
        # aname プラグインはとりあえず無視
        # uri として正しいかどうかもチェックしない
        if ( $line !~ /^\s+/ ) {
            $line =~ s/\[\[(.*)(?:\:|>)(.*)\]\]/<a href="$2">$1<\/a>/g;
            $line =~ s/(''')(.*)(''')/<em>$2<\/em>/g;
            $line =~ s/('')(.*)('')/<strong>$2<\/strong>/g;
        }
        if ( $level > 1 ) {
            $line = '<h'.$level.'>'.$line.'</h'.$level.'>';
        }
    }

    # <body> タグが現れるまで無視されるので <body></body> でサンド
    $$cont = join( '', @body );
    $$cont = "<body>\n" . $$cont;
    $$cont = $$cont . "\n</body>\n";
}
1;

rssdiff.inc.php を RSS 2.0 対応に

rssdiff を RSS 2.0 対応に

で、PukiWiki の rssdiff プラグインをようやく RSS 2.0 対応にしました。基本的には何も変わってなくて、単にタグが変わったとか日付のフォーマットが変わった程度なので、とりあえず設定で 1.0 も吐けるようにしてあります。1

意味的にはこの方がいいのかなぁと思いつつ、また様子見。とりあえずここの Wiki や PC説教講座の Wiki の RSS は 2.0 で出すようにしました。

  1. 愚直に書き足したのでサイズが膨らんできました。 

想像力に対する挑戦かと思ってた

ソフトの動作しているスクリーンショットムービーを作る方法

あはは。るびま5号の増井さんのインタビューはやはりもどかしいらしい。

私はこの記事を読んで「これはオレに対する挑戦だな」と思ってましたよ。「よーしパパ想像力フル稼働しちゃうぞー」って感じ。でも結局「なんだかすごそう」くらいまでしか想像できませんでしたがorz

なんかとても楽しそうでよかったですよ。詳しいものは「どうせ発表してる内容なんだから」、どっか適当な Web に置いてさえあればそこへリンク張るだけで済んだのになと、少し残念に思いますがね。インタビューそのものではない、その中のソフトの動作を Web で分かりやすい形に起こすという作業は、なんかるびまの仕事とはちょっと違う気がするし。

窓立て

こんなものを教えてもらいました。

http://www.ksky.ne.jp/~seahorse/mtate2/

映画に出てくるような未来的なデスクトップも作れるかも!?なウィンドウをデスクトップ上で立体化して邪魔にならないようにするツール。実際、半透明の設定で使うとビデオ関係が弱い機械だとけっこう重いですが、パワーも画面の広さも余っている場合はけっこういいんじゃないですかね。

とりあえず、楽しいです(笑) 常用はしませんが;;

About

例によって個人のなんちゃらです