成らぬは人の為さぬなりけり

エンジニアライフをエンジョイする為のブログ

CoffeeScriptを書いてみる その2

前回は、
関数定義、文字列内変数展開をやってみました。
さて、今回のテーマは、、、

  • 可変長引数
  • レンジ
  • 比較演算子
  • 条件付き代入
  • 無名関数

をやってみたいと思います。

可変長引数

関数の引数に「...」をつけると可変長引数になります。

hoge = (ary...) ->
  console.log ary

hoge 1,2,3,4,5  

実行結果

[ 1, 2, 3, 4, 5 ]

ちゃんと配列で取得できているようですね。

レンジ

配列をレンジ(範囲)で作成することができます。
書き方はRubyとほぼ同じでした。

range = [1..10]
console.log range

実行結果

[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

逆順にすることもできます。

reverse_range = [10..0]
console.log reverse_range

実行結果

[ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ]

「..」を「...」にすると、右端を含めないレンジになります。
※昇順でも降順でも同じ

reverse_range_2 = [10...0]
console.log reverse_range_2

実行結果

[ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]

比較演算子

等価比較

CoffeeSriptでは「==」を使うと「===」にコンパイルされます。
なので、==で型も含めた比較になります。
※CoffeeScriptにはJavaScriptでいう==に相当する比較演算子は無いそうです。

console.log 1 == "1"

実行結果

false

では、同じ事をJavaScriptでやってみます。
今回はNode.jsを使ってやってみます。

$ node
> 1 == "1"
true
> 1 === "1"
false

「1=="1"」はJavaScriptではtureになりますね。

「==」以外にも「is」という演算子が用意されています。

coffee> 1 is "1"
false

※ファイルに書くのがめんどくさくなってきたので、辞めました。。。
「is」は「===」にコンパイルされるようです。
他にも自然言語でかける演算子がいくつか用意されています。

coffee> 1 is "1"
false
coffee> 1 isnt "1"
true
coffee> not true
false
coffee> not 1
false
coffee> not undefined
true
coffee> not null
true
coffee> true and false
false
coffee> yes
true
coffee> no
false
coffee> false or true
true

こういうのはコードが非常にリーダブルになるので好き。

存在確認をする演算子もあります。

coffee> hoge?
false

RubyActiveSupportのObject#tryのような使い方もできます。

coffee> hoge?.foo
undefined
coffee> hoge = {foo: "foo"}
{ foo: 'foo' }
coffee> hoge?.foo
'foo'

条件付き代入

nullもしくは、undefinedの場合のみ代入する。
foo = null
foo ?= "foo"
console.log foo

実行結果

foo

※これはREPLからやると、エラーになる、、、

ちなみに、「?=」で代入する場合、変数「foo」は定義されている必要があります。
fooが未定義の場合


Error: In foo.coffee, the variable "foo" can't be assigned with ?= because it has not been defined.

と怒られました。

falseの時のみ代入する
bar = false
bar ||= "bar"
console.log bar

実行結果

bar

ちなみに、これもbarが定義されていないと怒られます。
これは、Rubyと同じで、条件的にfalseと判定できればなんでもいけるのか??
というわけで試してみます。

a = false
a ||= "Yes"
console.log a

b = 0
b ||= "Yes"
console.log b

c = null
c ||= "Yes"
console.log c

d = undefined
d ||= "Yes"
console.log d

e = ""
e ||= "Yes"
console.log e

実行結果

Yes
Yes
Yes
Yes
Yes

なるほど。
変数が定義されてさえいれば、あとはRubyと同じようなノリなのかな。

変数が定義されていない場合に代入する、というのは、こんな感じで書くんでしょうか?

coffee> hoge = hoge ? "hoge"
'hoge'

無名関数

最後に、無名関数を関数の引数に渡す場合の書き方です。
基本的には、関数定義時となんらかわりありません。

setTimeout ->
  console.log "Hoge"
, 1000

実行結果

$ coffee nameless.coffee                                                                                                    
Hoge

一秒待って、Hogeと表示されます。
ちなみに、当たり前な事ではありますが、こう書くと、意図しない動きになります。。。

setTimeout ->
  console.log "Hoge"
  , 1000

実行結果

$ coffee nameless.coffee                                                                                                    
Hoge 1000

setTImeoutに対して、

console.log("hoge",1000)

を呼び出す関数を渡した事になるので、当たり前ではありますが、
最初ちょっと???になりました。
(インデントに慣れていないので、、、)

今日はここまで。
次は配列の操作とかクラス定義とかやろうと思ってます。