CoffeeScript の機能と文法
【目次】
- 式と関数
- 条件分岐、論理演算
- 種々のデータ型
- 繰り返し
前準備
CoffeeScript 処理系のインストールが済んでいること.式と関数
対話型の CoffeeScript 処理系の起動と終了
coffee
CTRL キーと「d」の同時押し

式と評価結果
処理系に式を与えると,処理系は式の評価結果を出力する.
180 * 1.05

* これ以降は、対話型の CoffeeScript 処理系の起動と終了の手順の説明をいちいち書くことはしない.
四則演算, 括弧
式は, 数字と四則演算と括弧の組み合わせ などで書くことができる。
CoffeeScript では, 四則演算のための記号は半角文字の +, -, *, / である. 掛け算は全角の「×」ではなく、「*」であることに注意してほしい
100 + 200 + 300
10000 - 780
98 * 12 * 1.05
5 / 4
3 / 2

上の例で分かるように、割り算で割り切れないとき, 評価結果は小数になる, 次の例で,「5 / 7」 の評価結果が小数点以下 16 桁しか表示されていないことから分かるように,割り切れない時は、有限桁での近似計算になっている.
7 / 5

今度は,20桁と40桁の数の掛け算の例である. これも近似計算になっている. 「e+58」は「10 の 58 乗」という意味である
12345678901234567890 * 1000000000000000000010000000000000000000

今度は足し算の例である.0.0000000001 を足したのに、評価結果が 1000000000 のままになっている.これも近似計算になっている.
1000000000 + 0.0000000001

今度は これも近似計算になっている.
10 - 8 * 1.2

括弧は計算の優先順序を決める
10 - 8 * 2
(10 - 8) * 2

変数,代入
変数に値を結びつけることができる. 以下,変数に値を結びつけることを代入という. 何らかの値が代入されているような変数は、 式の中でつかうことができる。
a = 10
a * 1.05

同じ変数で代入を再度行うと,最新の値が使われる.古い値は消える.
b = 20
b * 1.05
b = 30
b * 1.05

CoffeeScriptでは,変数に代入されるのは値であって、式や変数ではない. 以下のように x = a という代入では, x の値として 10 が代入される. その後 a = 20 という代入により,a の値が 20 に変化するが、このことによって x の値が変化するようなことはない.
a = 10
x = a
a = 20
x * x

関数,引数
まず、処理系ですでに定義済みのプロパティの例を挙げる.
- Math.E : 自然対数の底
- Math.LN10 : 10 の自然対数
- Math.PI : 円周率

プロパティとは、何らかの記号に値が結びついたもの. 処理系で定義済みのプロパティに、値を代入しようと思ってはいけない。

関数とは,何らかの値を与えると,評価結果が返ってくるもの. CoffeeScript には次のような関数がある(ここに挙げている「関数」は、正確には,Math オブジェクトのメソッドである.オブジェクト、メソッドの説明はここでは行わない).
◆ Math
- Math.abs : 絶対値
- Math.max, Math.min : 最大値,最小値
- Math.ceil, Math.floor
- Math.random 擬似乱数(0から1未満の値)
- Math.sqrt : 平方根
- Math.pow : べき乗
- Math.exp, Math.log : 指数,対数
- Math.sin, Math.cos, Math.tan, Math.asin, Math.acos, Math.atan : 三角関数


このように,処理系で定義済みの関数には 名前がある. 関数に与える値のことを引数という. 例えば「Math.sqrt 9」では,引数は「9」である.
関数定義
自分で新しい関数を定義できる. このとき,仮引数(関数の引数が自動的に代入される変数のこと)の名前,関数の本体を書く.
長方形を求める関数の定義。仮引数は width と height。本体は「width * height」. 関数が生成され、area_rectangle という変数に代入される.(関数も値の一種だということです)。
area_rectangle = (width, height) -> width * height

いま定義した関数を使ってみる。

いろいろな関数を定義して使ってみる
- 円の面積
area_disk = (radius) -> 3.14 * radius * radius area_disk 5 area_disk 10
- 円周の長さ
circumference = (radius) -> 2 * Math.PI * radius circumference 5 circumference 10
既定値の例.次の関数定義では,qty の既定値を 1 にしている
f = (price, qty = 1) -> "price is #{price}, qty is #{qty}"
f 100
f 250 2

評価結果と副作用
処理系が式を評価するとき,式の評価結果が得られるだけでなく, 画面が変化したり,変数の値が変化したりなどの副作用が起きることがある.
console.log "Hello"
下の動作画面には,変数 a の値がないことに注意.つまり、「colsol.log "hoge"」の評価結果は何もないということです.

条件分岐、論理演算
条件分岐を1行で書く場合
条件分岐を1行で書く場合は, 「if <式> then <式>」や 「if <式> then <式> else <式>」のように書く. (他の書き方もありますが,説明は省略します)
p = if ( age < 13 ) then 800 else 1600
a = if ( age >= 20 ) then 0

プログラムファイル中で条件分岐を複数行で書く場合
CoffeeScript のプログラムをファイルに保存し, CoffeeScript の処理系を使ってコンパイル、実行する場合についてでです. ファイル中で条件分岐を複数行で書くときは then を使いません。
length = 50
if ( length < 100 )
console.log "small"
else
console.log "big"


「else if」のように書いて,多分岐ができる.
age = 12
if ( age < 6 )
console.log "100 yen"
else if ( age < 13 )
console.log "200 yen"
else
console.log "500 yen"


論理式
論理式では,次に挙げたような演算子などを使う
- is : 等しい
- isnot : 等しくない
- <, <=, >, >= : 比較演算子
- and, or, not : 論理演算子
種々のデータ型
- 数値 numerical
16進数の場合には「0x」をつける
- ブール値 boolean
true, false などは真偽を表す値である。
- 文字列
文字列は, シングルクオーテーションか ダブルクオーテーションで囲む. ダブルクオーテーションの内部では式展開(後述)が行われる. シングルクオーテーションのときは式展開は行われない.
文字列操作には次のようなものがある
- + : 文字列の連結
- length : 文字列の長さ
- split : 区切りを指定して,文字列を配列に変換
console.log "hoge" + " hoge2" console.log "hoge".length console.log "I have a pen".split(' ')
文字列における式展開の例を示す.
x = 100 console.log "x = #{x}" console.log " #{ x * 100 } is x * 100"
「 ''' 」 で囲むと ヒアドキュメントになる
CoffeeScript のプログラムをファイルに保存し, CoffeeScript の処理系を使ってコンパイル、実行する場合で, 文字列が複数行にわたるときには,ヒアドキュメントが便利.ヒアドキュメントでは, 各行の先頭の空白文字は自動的に除去される
SQL = ''' SELECT * FROM R WHERE id = 101; '''
- 配列
配列は要素を「,」で区切る.全体を「[」と「]」で囲む.
L = [1, 2, 3] A = ["red", "green", "blue", "yellow", "black"] B = ['toast', 'cheese', 'wine']
連番は,最初の値と最後の値の間に「..」を書く.
L1 = [0..10] L2 = [10..0]
添字によるアクセスの例. 添字は 0 から始まることに注意(配列の先頭要素の添字が 0)
A = [1..5] A[1] = 5 A A[2..4] = [1, 2, 3] A
配列がある値を含むかを調べるには in を使う
100 in [100, 200, 300]] 400 in [100, 200, 300]
配列は入れ子にできる.
L = [ [1, 0, 0], [0, 1, 0], [0, 0, 1] ]
- オブジェクト
CoffeeScript のオブジェクトは,連想配列のように使える(例えば、下のように「 p["x"] 」のような書き方ができる。
p = {x:100, y:500, color:"red"}
上の例と同じことを次のように書くこともできる.
p = [] p["x"] = 100 p["y"] = 500 p["color"] = "red"
オブジェクトを入れ子にすることができる
participants = { '1': { name: 'hoge', age: 21 }, '2': { name: 'hoge2', age: 22 } }
CoffeeScript のプログラムをファイルに保存し, CoffeeScript の処理系を使ってコンパイル、実行する場合は, 上と同じことを複数行に分けて、次のように書くことができる.字下げがオブジェクトの構造を示している
participants = 001: name: "hoge" age: 21 002: name: "hoge2" age: 22
繰り返し
繰り返しには while や for などを使う.配列と繰り返し
- 配列の各要素に同じ処理を繰り返して、新しい配列を作る
「( 」と「)」を忘れないように。
A = ( i * 1.05 for i in [100, 200, 300] )
- 配列の要素の中で条件を満足するものだけを,別の配列に挿入する
L = [] L.push i for i in [30, 5, 28, 4] when i > 10
if を使って書きなおすと次のようになる.
L = [] ( if i > 10 then L.push i ) for i in [30, 5, 28, 4]
- 二重ループの例
A = ( "#{i} * #{j} = #{i * j}" for i in [1..4] for j in [1..5] )
- ループ内で添字番号の取得
"i = #{i}, j = #{j}" for i, j in [100, 200, 300]
オブジェクトと繰り返し
オブジェクトで for を使うと、ループ変数にはキー値がセットされる.
obj = {x:100, y:500, color:"red"}
X = ( "#{k} : #{obj[k]}" for k of obj )

関数や変数に関する追加説明
変数がすでに値に結び付けられているかを調べる
a = 100
foo = (x) -> x + 1
a?
foo?
b?
foo2?

関数とスコープ
関数の本体に複数の式が並んでいるとき、最後の式の評価結果が関数全体の評価結果になる 関数の内部で、何かの変数の代入が行われても、関数の外側には影響しない。 x
hoge = -> y = 2; x = 3
y = hoge()
