2011年9月19日月曜日

一括バイトコンパイル



emacs -batch -f batch-byte-compile *.el





2011年9月18日日曜日

emacsclient



emacs23.1以降の--daemonを使用


設定


.emacs



(require 'server)
(unless (server-running-p)
(server-start))
(defun iconify-emacs-when-server-is-done ()
(unless server-clients (iconify-frame)))
(add-hook 'server-done-hook 'iconify-emacs-when-server-is-done)
(global-set-key (kbd "C-x C-c") 'server-edit)
(defalias 'exit 'save-buffers-kill-emacs)
(add-hook 'server-visit-hook
(lambda ()
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
))




.bashrc or .zshrc



export EDITOR=emacsclient
export VISUAL=emacsclient



使用


emacs --daemon
emacsclient FILENAME





2011年9月17日土曜日

emacsでファイル横断検索後、バッファ置換



インストール


M-x install-elisp-from-emacswiki igrep.el
C-c C-c
M-x install-elisp-from-emacswiki grep-edit.el
C-c C-c
M-x eval-current-buffer


検索結果のバッファを置換。


M-x igrep-find
置換 'M-%
正規表現で置換 M-C-%
後方参照は\[\]で囲ったものを、\&で参照するみたい。

これ合ってる?
M-x query-replace-regexp では\(\)で囲ったものを、\数字で後方参照する。


置換後の操作


C-c C-e 全変更保存
C-c C-f リージョンの変更破棄
C-c C-u 全変更破棄


文字コードに依存しないlgrep


apt-get install lv
igrepの代わりに使用するだけ。
ただし、サブディレクトリを再帰的に処理するオプションがない。
自分でfindを使用したaliasを作成する必要がある。





2011年9月11日日曜日

サイ本5版 1部「コアJavaScript」  5章「式と演算子」



算術演算子



  • 除算

    • 0で割ると、Infinityか-Infinity

    • 0/0はNaN(NaNの型はnumber)





IN演算子(プロパティの所属を調べる)


オブジェクトのプロパティであればtrueを返す。
左側オペランドは文字列か文字列に変換されるものでなければならない。


instanceof演算子(インスタンスの所属を調べる)


クラス(コンストラクタ関数)のインスタンであればtrueを返す。
右側のオペランドがクラスでない場合は、実行時エラーを返す。


文字列演算子



  • +演算子は文字列を優先する

    • どちらか一方が文字列なら数値は文字列に変換される



  • 比較演算子は数値を優先する

    • どちらか一方が文字列なら、文字列は数値に変換される。





ビット演算子


  • オペランドに整数が必要

  • ビット演算子は、内部で浮動小数点形式から32bitの整数形式に変換する

  • 右シフトは符号付き>>と符号無し>>> 演算子の2種類がある



代入演算子


  • 結合性は右から左

    • i = j = k = 0;



  • 左側オペランドは代入された値を参照する



typeof演算子



  • objectと判定されるもの

    • オブジェクト(配列、Number,String,Boolenラッパーオブジェクト、Date,RegExpなど)

    • null

    • クライアントサイドオブジェクト



  • 他の型

    • function

    • number

    • string

    • boolen

    • undefined





オブジェクトの型を知る

typeofではobjectとしか判定されないので、instanceof演算子やconstructorプロパティを使用して、
詳しく調べる。


delete演算子


削除に成功すると、true,失敗するとfalesを返す



  • 削除できないのも

    • コアのプロパティやクライアントサイドのプロパティには削除できないものがある

    • var文で宣言された変数





存在しないプロパティに対してもtrue

ECMAScript標準ではオペランドがプロパティや配列要素、変数でない場合もtrueを返す仕様になっている。


プロパティの参照先を削除するわけではない

プロパティの参照先を削除するのは、GCのお仕事


void演算子


void 0 でundefinedと同じ効果。
undefinedが規定されたのは、ECMAScript v3, 実装されたのはJS1.5
古いバージョンとの互換性を気にするならvoid 0


.演算子と、[]演算子



  • .は識別子、[]はプロパティにアクセスする

  • 変数などを使用して動的にプロパティにアクセスする場合は[]を使用する



関数実行演算子()


即時関数とかでよく使いますね。





2011年9月10日土曜日

サイ本5版 1部「コアJavaScript」  7章「オブジェクトと配列」



プロパティの存在確認


inとundefined
大抵はundefinedを使用する。


in

if ( "hoge" in obj ) obj.hoge = 1;


undefined

if ( obj.hoge !== undefind) obj.hoge = 1;


両者の違いはプロパティが存在するかどうか


obj.hoge = undefined;


のように、プロパティ自体が存在する場合は、
inはtrueになる。


プロパティごと削除


delete演算子を使用する。


Objectオブジェクトのプロパティとメソッド


constructorプロパティ

オブジェクトを生成したコンストラクタ関数を参照している。
instanceof演算子はconstructorプロパティを調べている。


toString()メソッド

toStringメソッドは引数をとらない。
オブジェクトが文字列に変換されるときに暗黙的に使用される。
例えば



  • +演算子で文字列とオブジェクトを結合

  • alert(),document.write()に渡すとき


そのままではあまり役に立たないので、多くのオブジェクトで独自のtoStringが定義されている。



  • 配列

    • 文字列に変換された要素リスト



  • 関数

    • 関数の定義





toLocalString()メソッド

JP,USなど、ロケールによって返す文字列を変化させる。
ECMAScript v3 ではArray,Data,NumberのtoLocalString()メソッドは
ローカライズされた文字列を返すように規定されている。


valueOf()メソッド

オブジェクトを文字列以外の基本型に変換するときに呼び出される。
デフォルトでは何もしない。
Date.valueOf()など、一部のオブジェクトは独自のvalueOf()を持つ。


hasOwnProperty()メソッド

hasOwnPropertyを呼び出したオブジェクト(obj)が引数hogeをプロパティにもつか。
継承したものはfales



obj.hasOwnProperty("hoge")



propertyIsEnumerable()メソッド

hasOwnProperty()とほぼ同じ。
propertyIsEnumerable()はhasOwnProperty()と同じ動作かつ、for/inで調べられる場合にtureを返す。
しかし、for/inで調べられないプロパティは、ほとんどの場合継承したもの。
だからhasOwnProperty()とほぼ同じ。


isPrototypeOf()メソッド

呼び出したオブジェクトが引数で指定したオブジェクトのプロトタイプであるときture



var o = {};
Object.prototype.isPrototypeOf(o); // o.constructor == Object
Function.prototype.isPrototypeOf(Object); //Object.constructor == Function



配列


配列はオブジェクトに少々機能を追加したもの。
typeof演算子でも「Object」と表示される。
簡単に説明するために、配列とオブジェクトは別のものとして扱う。


使用可能なインデックス

0~2^31-2の正の整数
これ以外では文字列として扱われプロパティ名になる。


オブジェクトに配列要素を追加

オブジェクトに「0」という名前のプロパティを追加。(0は文字列ではない)
これは配列の要素を追加しただけで、オブジェクトが配列になるわけではない。


要素はdeleteで削除できない

deleteはプロパティそのものを削除するが、
配列の要素で使用した場合はundefinedを設定するだけ。
配列の要素自体を削除する場合は、shift(),pop(),splice()など配列メソッドを使用する必要がある。


lengthプロパティ

配列の最大index+1の値を保持。
配列に変化があると自動的にlengthも変化する。
配列のインデックス最大値は2^32-2なので、lengthの最大値は2^32-1


lengthプロパティに値を書き込む

lengthに現在の値より小さい値を代入すると、配列の長さが切り詰められ、要素は中の値とともに廃棄される。
現在値より大きな値を代入すると、拡張された分の要素にはundefinedが入る。


配列のメソッド


  • concat()


配列に要素を追加して新しい配列を作成
引数に与えた配列は要素に展開される。
しかし再帰的には展開されない



var a = [1,2,3];
a.concat(4,5) //[1,2,3,4,5]
a.concat([4,5]) //[1,2,3,4,5]
a.concat([4,5,],[6,7]) // [1,2,3,4,5,6,7]
a.concat(4,[5,[6,7]]) // [1,2,3,4,5,[6,7]]




  • slice()

    • 非破壊的。

    • 2番目の引数で指定された要素の直前までが格納される。





  • splice()

    • 破壊的。削除と挿入を同時に行える。削除した分は返される。

    • 1,2引数は削除用、それ以降の引数は挿入用。





var a = [1,2,3,4,5];
//index2から長さ0で削除。つまり削除しない。
//index2の位置から挿入
a.splice(2,0,'a','b'); //aは[1,2,'a','b',3,4,5]
a.splice(2.2,[1,2],3); //['a','b']が返される、aは[1,2,[1,2],3,3,4,5]






  • JavaScript1.6から実装された配列メソッド

    • indexOf(), lastIndexOf(), forEach(), map(), filter()





  • indexOf(),lastIndexOf()

    • 指定した値を配列から高速に検索



  • forEach()

    • 配列の各要素を引数に、指定した関数を実行する。



  • map()

    • forEach()かつ関数から返された値を配列にまとめて返す。perlのmapと同じ。



  • filter()

    • forEach()かつ関数から返された値がtrueの要素だけ抜き出す。perlのgrep。





配列のようなオブジェクト


配列はオブジェクトの一種だが、特別。特にlengthプロパティ。
配列のようなオブジェクトはJSで多用する。
Argumentオブジェクトや、document.getElementByTagName()メソッドなどが返すオブジェクト





サイ本5版 1部「コアJavaScript」  6章「文」



式とは


評価して値が生成されるもの
=演算子のように副作用を起こすこともあるが、通常式自体は何もしない。

文とは


JSに何かをさせるのもの(副作用のあるもの)

式文


副作用を伴う式が最も簡単な文


  • 代入文 s = "aaa"+ "bbb", i *= 3

  • counter++

  • delete o.x

  • 関数実行()

    • 何もしない関数は実際にはありえないので式文。

    • function文自体は静的な定義をするだけなので、厳密には文ではない。動的なものが文。



式にはセミコロンが必要


文ブロック


{}は複数行を1行として扱う。
ifやfor、returnで使用される。

for/in文


オブジェクトのプロパティを取り出して処理。

オブジェクトのプロパティの名前をすべて配列にコピー
for(a[i++] in o){}



  • for/inループの中で、プロパティを削除すると、そのプロパティはfor/inで処理されない。

  • ループの中で新しいプロパティを定義した場合、for/inループで処理されるかはJSの実装による。

  • for/inはすべてのプロパティを調べられるわけではない



function文


関数定義時に実行されるのではなく、実行演算子()で実行される。
定義は事前にコンパイルされ新しく関数オブジェクトが生成される。
この関数オブジェクトは関数名をプロパティ名とした(グローバルオブジェクトまたはCallオブジェクトの)プロパティに関連付けられる。
事前に解析されているので、function文の定義より前の行で実行できる。

補足

CallオブジェクトはActivateオブジェクトのこと。AvtivateはECMA仕様で使用されてる名前。




2011年9月7日水曜日

サイ本5版 1部「コアJavaScript」  3章「データ型と値」 3.13~3.15.4



オブジェクトから基本データ型への変換


nullでないオブジェクトは必ずtrueなので、falseに変換されるような値を持つオブジェクトでもtrueになる。



new Boolean(false)
new Number(0)
new String("")
new Array()



valueOf()メソッドとtoString()メソッドによる型変換

オブジェクトが数値に変換される場合



  • まずオブジェクトのvalueOfメソッドを呼び出す。

  • たいていは継承を遡り、ObjectのvalueOf()を実行。これは何もせずにオブジェクトを返す。

  • 次に、toString()メソッドが呼ばれ、文字列に変換

  • 文字列が数値に変換される。


要素が2つ以上の配列は"3,4,5"のような文字列から数値に変換することになるので、NaNになる


コンテキストによる型変換

+,比較演算子はコンテキストが曖昧なことがあり、この場合は↑のとおり、valueOf(),toString()が呼び出される。



  • Dateオブジェクトは例外

    • Dateオブジェクトは自分でvalueOf()とtoString()を持っているため、valueOf()で数値に変換される。

    • たいていのオブジェクトはvalueOf()を持っていない



  • valueOfは数値に変換するメソッドではない。「意味のある値」に変換するためのものであり、文字列を返してくることもある。



値と参照のルール



  • 基本型は値渡し、それ以外は参照

    • オブジェクトは参照。関数、配列もオブジェクトなので参照。



  • a = b;としたとき、aとbは同じ値をもつ別の変数なのか、それとも同じものをさす参照なのかは、変数に代入するものによる。

    • b=[1,2];など参照型ならa===b,

    • b = 1;なら、a==b




文字列は参照型か?


  • 実装による?

  • 文字列は不変(immutable)なので、どちらでもあまり関係ない。

  • ただし、同じ内容の文字列なら==でtrueになるので、このときは値により比較している。





2011年9月6日火曜日

サイ本5版 1部「コアJavaScript」  4章「変数」



var宣言



  • varで宣言された変数は永続し、deleteで削除しようとするとエラーになる

グローバルオブジェクト


JavaScriptインタプリタが起動されると、コード実行前にグローバルオブジェクトが生成される。
グローバル変数を宣言するとは、このオブジェクトのプロパティを定義すること。
グローバルオブジェクトを生成したのち、初期化で、予め定義した値や関数を参照するプロパティをグローバルオブジェクトに設定する。Mathオブジェクトを指すMathプロパティや数値の無限大値を指すInfinityなど。

ローカル変数


Callオブジェクトのプロパティ

実行コンテキスト



  • 関数を実行するたびに、関数ごとに実行コンテキストを作成する。

  • これにより、変数をグローバルにするか、どの関数のCallオブジェクトにするか決める。

  • グローバルは複数あることも。

  • クライアントJSではウインドウやフレームごとに、それぞれ異なるグローバル実行コンテキストが定義される。これらの複数のグローバル実行コンテキストは相互参照することが可能。(相互参照はセキュリティ問題になる。13章で詳しく説明)




2011年9月5日月曜日

サイ本5版 1部「コアJavaScript」  3章「データ型と値」 3.1~3.12



数値


すべての数値は浮動小数点。IEEE754標準の64bit浮動小数点形式。
数値リテラルはマイナス記号で反転できるが、マイナス記号は単項演算子とみなされ、数値リテラルの一部ではない。


整数リテラル


8進数はECMAScriptでは規定されていないので、使用しないほうがいい。


浮動小数点リテラル


[数値][.数値][e|E[(+|-)]数値]
6.02e23 -> 6.02x10^23


特殊な数値


浮動小数点値の表現可能最大値を超えると「Infinity」となる。マイナス側は「-Infinity」
未定義な演算結果はNaN(Not a Number)になる。これは自分自身を含めていかなる数値とも合致しない。
isNaN()という関数を使用する。
上記のInfinity、-Infinity、NaNでないことをテストするにはIsFinite()
Finite([形]有限な)


エスケープシーケンス



  • \xXX

    • Latin-1



  • \xXXXX

    • Unicode



  • \XXX

    • 8進数Latin-1 ECMAScript v3ではサポートされてないので使用しない





文字列の操作


文字列中の特定の文字は配列表記を用いて読み込み可能。
しかし、ECMAScript v3 でサポートされてないので、charAt()を使用する



last_char = s.charAt(s.length - 1);


数値から文字列への変換



var n = 100;
var str = n + "";
var str = String(n);
var str = n.toString(10); //10進数で。省略可



有効桁数や指数表示を指定して数値->文字列変換


JS1.5以前は欠点があり、小数点以下の桁数の指定や、指数表示の指定方法が用意されていなかった。
JS1.5ではNumberクラスに数値から文字列に変換するメソッドが3つある。



// すべて四捨五入される
var n = 123456.789;
//小数点桁数指定
n.toFixed(0); //123457
n.toFixed(2); //123456.79
//指数表示指定
n.toExponential(1); //1.2e+5
n.toExponential(3); //1.235e+5
//有効桁数指定。有効桁数より大きい場合は、指数表示
n.toPrecision(4); // 1.235e+5
n.toPrecision(7); // 1.23456.8



文字列から数値への変換


"5"*"2"
"5"-0
Number(" 5 ") //前後に空白があってもいい
parseInt("15px") //15 後の文字列は無視される。第2引数で進数指定できる。
parseFloat("15.5px") //15.5


+は文字列結合と解釈されるので不可。
parseInt,parseFloatで数値に変換できないとNaNになる。


論理値への型変換


論理値コンテキストで変換されるが、明示的に変換する場合は
Boolen(x);を使用するか、!!xとする。



  • trueに変換されるもの

    • 0とNaN以外,

    • 空文字列以外,

    • nullでないオブジェクト、関数、配列





オブジェクト


配列

連想配列と異なり、インデックスが正の整数。
コンストラクタ new Array()は new Array(1,2)は[1,2]を表すが、new Array(2) は配列の大きさを表し[undefined,undefined]になる。
これが紛らわしいので、配列はリテラルで記述するのがいい。


基本型ではないオブジェクト


Dateオブジェクト

基本型ではないが、Dateコンストラクタで日時の設定取得ができる。


RegEXPオブジェクト

リテラルのほうが簡潔だが、リテラルはコンパイル時に一度しか生成されないので、
動的に生成する場合はコンストラクタを使う。


Errorオブジェクト


  • Error

  • EvalError

  • RangeError

  • ReferenceError

  • SyntaxError

  • TypeError

  • URIError


が定義されている。


null値(=値がない)


CやC++ではnullは0と同じだがJSは違う。nullはnullであり、コンテキストにより変化する。



  • コンテキスト

    • 論理値コンテキストではfalse

    • 数値コンテキストでは、0

    • 文字列コンテキストでは"null"





undefined (=未定義値)



  • 宣言されているが値が設定されていない(初期化されていない)変数

  • 存在しないオブジェクトプロパティ


を使おうとすると未定義値が返ってくる。



  • (null == undefined)はtrue

  • (null === undefined) はfalse

  • コンテキスト

    • 論理値コンテキストではfalse

    • 数値コンテキストではNaN

    • 文字列コンテキストでは"undefined"





型変換まとめ表


本のP39