CoffeeScript クラス定義メモ
class Hoge # private static member (Is accessible from all members.) _aaa = 0 _bbb = 0 # public static member @getAAA = () -> _aaa @getBBB: () -> _bbb # constructor constructor: (@a, @b, aaa) -> # Variables 'a' and 'b' are defined as public instance members. _aaa = aaa _bbb = aaa * 2 # private instance member (Is not accessible from public methods.) _c = a * b # privileged instance member this.getC = () -> _c # public instance member getA: () -> @a getB: () -> @b h1 = new Hoge(1, 2, 10) h2 = new Hoge(3, 4, 20) alert(h1.getA() + ", " + h1.getB() + ", " + h1.getC()) # 1, 2, 2 alert(h2.getA() + ", " + h2.getB() + ", " + h2.getC()) # 3, 4, 12 alert(Hoge.getAAA()) # 20 alert(Hoge.getBBB()) # 40
わかりづらい・・・。
全部 public にして、外部からアクセスして欲しくないメンバーには接頭辞に _ を付ける、ってスタンスがいいと思う。
あと、紛らわしいから static メンバーには @ じゃなくてクラス名を使う方がいいかな。
class Hoge # static member Hoge._aaa = 0 Hoge._bbb = 0 Hoge.getAAA = () -> Hoge._aaa Hoge.getBBB = () -> Hoge._bbb # constructor constructor: (@_a, @_b, aaa) -> Hoge._aaa = aaa Hoge._bbb = aaa * 2 @_c = @_a * @_b # instance member getA: () -> @_a getB: () -> @_b getC: () -> @_c h1 = new Hoge(1, 2, 10) h2 = new Hoge(3, 4, 20) alert(h1.getA() + ", " + h1.getB() + ", " + h1.getC()) # 1, 2, 2 alert(h2.getA() + ", " + h2.getB() + ", " + h2.getC()) # 3, 4, 12 alert(Hoge.getAAA()) # 20 alert(Hoge.getBBB()) # 40
[おまけ]
一つ目のスクリプトから変換された JavaScript
Hoge = (function() { var _aaa, _bbb; Hoge.name = 'Hoge'; _aaa = 0; _bbb = 0; Hoge.getAAA = function() { return _aaa; }; Hoge.getBBB = function() { return _bbb; }; function Hoge(a, b, aaa) { var _c; this.a = a; this.b = b; _aaa = aaa; _bbb = aaa * 2; _c = a * b; this.getC = function() { return _c; }; } Hoge.prototype.getA = function() { return this.a; }; Hoge.prototype.getB = function() { return this.b; }; return Hoge; })(); h1 = new Hoge(1, 2, 10); h2 = new Hoge(3, 4, 20); alert(h1.getA() + ", " + h1.getB() + ", " + h1.getC()); alert(h2.getA() + ", " + h2.getB() + ", " + h2.getC()); alert(Hoge.getAAA()); alert(Hoge.getBBB());
二つ目のスクリプトから変換された JavaScript
Hoge = (function() { Hoge.name = 'Hoge'; Hoge._aaa = 0; Hoge._bbb = 0; Hoge.getAAA = function() { return Hoge._aaa; }; Hoge.getBBB = function() { return Hoge._bbb; }; function Hoge(_a, _b, aaa) { this._a = _a; this._b = _b; Hoge._aaa = aaa; Hoge._bbb = aaa * 2; this._c = this._a * this._b; } Hoge.prototype.getA = function() { return this._a; }; Hoge.prototype.getB = function() { return this._b; }; Hoge.prototype.getC = function() { return this._c; }; return Hoge; })(); h1 = new Hoge(1, 2, 10); h2 = new Hoge(3, 4, 20); alert(h1.getA() + ", " + h1.getB() + ", " + h1.getC()); alert(h2.getA() + ", " + h2.getB() + ", " + h2.getC()); alert(Hoge.getAAA()); alert(Hoge.getBBB());
スマートフォンアプリ選手権にエントリーしてみた
@IT デザインハックミーティング 「スマートフォンアプリ選手権」
おとといの夜にエントリーメール送ったんだけど、App Hub無料開発者コード貰えました><
今のところ「おばか賞」を狙おうかと思ってます(`・ω・´)
F# の書式指定文字列
printf 使ってるとすぐに気付くんだけど
let s = "hoge" printfn s
これ、コンパイル通らないですね。
error FS0001: 型 'string' は型 'Printf.TextWriterFormat<'a>' と互換性がありません
Console.WriteLine みたいに単純に文字列を受け取るわけじゃないみたいです。
こういう間違った指定もコンパイルエラーになります。
printfn "%s, %i" 100 200
つまり、コンパイル時に文字列リテラルを解析して各プレースホルダーの型を解決できちゃう、と。
これはなかなか粋なことしてくれます!
ちなみに Printf.TextWriterFormat<'a> は PrintFormat<'a, System.IO.TextWriter, unit, unit> の型省略形です。
次の検証結果を見るとよくわかりますが、文字列リテラルを直接 PrintfFormat 型として扱うことができるってことですね。
> let format:PrintfFormat<_,unit,unit,unit> = "%s %i";;
val format : PrintfFormat<(string -> int -> unit),unit,unit,unit>
PrintfFormat のコンストラクタの引数に対しては解析処理は働きません。これは文字列リテラルを普通に string 型の引数として渡しているだけだから当然です。
> let format = new PrintfFormat<_,unit,unit,unit>("%s %i");;
error FS0030: 値の制限。値 'format' は次のジェネリック型を持つと推論されました。 val format : PrintfFormat<'_a,unit,unit,unit> 単純なデータ用語として 'format' を定義するか、明示的な引数を使用して関数にするか、ジェネリックにする意図がない場合は型の注釈を追加してください。
とりあえず言語の基本機能はなんとか覚えたと思うのです
let FizzBuzz = function | x when x % 15 = 0 -> "FizzBuzz" | x when x % 3 = 0 -> "Fizz" | x when x % 5 = 0 -> "Buzz" | x -> string x >> printfn "%s" |> List.iter FizzBuzz [1..100]