RequestPolicy じゃなくて RequestPolicy Continued にしたら捗った
いままで、RequestPolicy を愛用していたんだけど、全然更新されていないのに気がついたので、RequestPolicy Continued に切り替えた。
(๑´ڡ`๑) めっちゃ使いやすい
class が export キーワードで export できなくてちょっと悲しかった
node のバージョンはこんな感じ:
% node --version
v6.3.1
wasp を書いてたら、
// ↓ class は書けるのに、export ができない!!!>< /* export */ class Emitter { constructor() { this.events = []; } on(name, cb) { this.events = ( this.events || [] ); this.events[name] = cb; return this; } emit(name, that) { let self = this; let events = self.events[name] || []; events.forEach( anEvent => { anEvent.call( self, that ); } ); return self; } } // ↓ ので、従来通りの module.exports に Emitter を設定する。 module.exports = Emitter;
という感じだったので、悲しい。
ビルドツール Wasp とかどうかな
Fly を見ていたらこういう風に書けたって良いんじゃないかなと思った:
const gcc = require( 'wasp-gcc' ); const paths = { scripts: [ 'src/**/*.c' ], dist: 'obj' }; export default function () { this.ready( 'build' ); } export function compile() { this.from( paths.scripts ) .gcc() .to( paths.dist ); }
うん、source()
とか target()
じゃなくて、from()
とか to()
って書けた方が良いと思う。
モジュールが Fly オブジェクトのメソッドを使えるようにするのってどうするんだーーーー?
Nemerle やってみた
インストール
yaourt でインストールできる:
% yaourt -S nemerle
へろーわーるど
using System; Console.WriteLine( "Hello, World!" );
このファイルを hello.n とすると、ncc
を使ってこんな風にコンパイルできる:
% ncc ./hello.n -o hello.exe
関数
関数は def
から始まる:
def add(a : int, b : int) : int { a + b; }
FParsec のチュートリアル的な何か
さて、今日は FParsec 日本語チュートリアルを読んでやってみるよ。
nuget
はインストールしてるかな?
私は nuget3
をインストールしてみたよ:
% yaourt -S nuget3
勉強用のディレクトリを作成しよう:
% mkdir ./hello-fparsec
% cd ./hello-fparsec
FParsec
をインストールしてみよう:
% nuget install FParsec -outputDirectory ./packages
-outputDirectory ./packages
を付けない場合、カレントディレクトリに FParsec
がインストールされてしまうので注意だ。
なので、Visual Studio の慣習に習って ./packages/ にインストールしてみた。
さっそく使ってみる
run
関数に何らかのパーサー関数と文字列を渡すと結果が返ってくる模様。
ʕ•͡ω•ʔ pfloat は FParsec 浮動小数点数をパースして浮動小数点数を返す組み込みのパーサー関数だぞ
// demo000.fsx open FParsec let test p str = match run p str with | Success(result , _, _) -> printfn "Success: %A" result | Failure(errorMessage, _, _) -> printfn "Failure: %s" errorMessage test pfloat "1.25" test pfloat "1.25E" test pfloat "1.25E 3"
それで、こんな風に打ってみると:
% fsharpi -I ./packages/FParsec.1.0.2/lib/net40-client/ -r "FParsec.dll" ./demo000.fsx Success: 1.25 Failure: Error in Ln: 1 Col: 6 1.25E ^ Note: The error occurred at the end of the input stream. Expecting: decimal digit Failure: Error in Ln: 1 Col: 6 1.25E 3 ^ Expecting: decimal digit
最初の test pfloat "1.25"
だけパースされた。
ヽ(=´▽`=)ノ
OCaml の Test::Simple を目コピしてみた その 4
OCaml のソースコードに沿って TAPDocument.ml を test-document.fs にして、TAPBuilder.ml を test-builder.fs に書いてみた。
なんかクラスっぽいやつでやってみたんだけど、これでいいのかな…………(汗
module Test.Builder type Plan(?count : int) = let current_plan : option<int> = count type TestCaseBuilder () = let mutable running_tests : (int -> Test.Document.node) list = []; member this.BuildTestCase(todo : option<string>, diag : option<Test.Document.diagnostic>, test : bool, description : string) = let running_test = fun number -> match todo with | None -> Test.Document.TestCaseNode((if test then Test.Document.Ok else Test.Document.NotOk), number, description, diag) | Some x -> Test.Document.TodoTestCaseNode((if test then Test.Document.Ok else Test.Document.NotOk), number, description, Test.Document.Todo(x), diag) running_tests <- running_test :: running_tests running_test member this.BuildDiagnostic(line : string) = let running_test = fun (_ : int) -> Test.Document.DiagnosticNode (Test.Document.Diag( [ line ] )) running_tests <- running_test :: running_tests running_test
今ブログ記事を書いてる時に気がついたけど、これじゃダメだよねwwwwww
だって、Plan とか let plan = Plan(12)
とかってしないとわかんないじゃんwwwwww
ほげーーーーーーー!!!
あと、F# では、関数に省略した引数を使えないので、type
のコンストラクタ?の引数に使わなければならない………
(。・_・。) ………
TestCaseBuilder
を TestCaseResult
とかにして、そのリストをどこかに持ったほうが良いのかも?
こんな感じ:
type TestCase(?todo, ?diag, test, description) = let running_test = fun number -> match todo with | None -> Test.Document.TestCaseNode((if test then Test.Document.Ok else Test.Document.NotOk), number, description, diag) | Some x -> Test.Document.TodoTestCaseNode((if test then Test.Document.Ok else Test.Document.NotOk), number, description, Test.Document.Todo(x), diag)
OCaml の Test::Simple を目コピしてみた その 3
続き。
ʕ•͡ω•ʔ TAPDocument.ml 完全目コピでけたー!
init_document
はなんか初期化しそう。
let init_document doc = let count = count_tests doc in let failures = count_test_failures doc in match doc with | Document(PlanNode(plan)::nodes) -> Document( PlanNode(plan)::nodes @ (if count = plan then [] else [ (create_count_footer count plan) ] ) @ (if failures = 0 then [] else [ (create_failure_footer count failures) ]) ) | Document(nodes) -> Document( nodes @ [ PlanNode(count) ] @ (if failures = 0 then [] else [ (create_failure_footer count failures) ]) )
後は文字列化する関数。
そんでさ、function Document(nodes) ->
は Warning 出るけど、どーすれば回避できるかわかんないって書いたけど、わかった。
let hoge Document nodes = ...
でいいみたい。
引数が複数あってわけわかんない場合は let piyo (Document nodes) =
みたいに括弧つけとこう。
let string_of_status status = match status with | OK -> "ok" | NotOk -> "not ok"
let string_of_diagnostic (Diag lines) = List.map (fun line -> "# " + line + "\n") lines |> List.fold (+) ""
let string_of_directive (Todo s) = "# TODO " + s
let string_of_node node = let emit_diagnostic diag = (match diag with | None -> "\n" | Some diag -> "\n" + (string_of_diagnostic diag)) in match node with | TestCaseNode(status, num, desc, diag) -> (string_of_status status) + " " + num.ToString() + " - " + desc + (emit_diagnostic diag) | TodoTestCaseNode(status, num, desc, dir, diag) -> (string_of_status status) + " " + num.ToString() + " - " + desc + (string_of_directive dir) + (emit_diagnostic diag) | DiagnosticNode(diag) -> (string_of_diagnostic diag) | PlanNode(count) -> "1.." + count.ToString() + "\n"
let string_of_document (Document nodes) = List.map string_of_node nodes |> String.concat ""
ここも。
全部のソースはここに置いてある。
OCaml の Test::Simple を目コピしてみた その 2
続き。
OCaml では文字列の結合は ^
だけど*1、F# では +
だ。
また、OCaml での string_of_int
は F# には存在しないけど、書くとしたらこんな感じになる:
let string_of_int (n:int):string = n.ToString()
DiagnosticNode
を返す関数 2 連発:
let create_failure_footer test_count failure_count = DiagnosticNode( Diag(["Looks like you failed " + failure_count.ToString() + " tests of " + test_count.ToString() + " run."]) )
let create_count_footer test_count plan_count = DiagnosticNode( Diag(["Looks like you planed " + plan_count.ToString() + " tests but " + (if test_count < plan_count then ("only ran " + test_count.ToString()) else ("ran " + ((test_count - plan_count).ToString()) + " extra")) + " ."]) )
*1:F# でも Warning は出るものの、使うことができる
OCaml の Test::Simple を目コピしてみた
これ。
モジュール名は Test.Builder
にしておく。
module Test.Builder type status = | NotOk | Ok type directive = | Todo of string type diagnostic = | Diag of string list type node = | TestCaseNode of status * int * string * diagnostic option | TodoTestCaseNode of status * int * string * directive * diagnostic option | DiagnosticNode of diagnostic | PlanNode of int type test_document = | Document of node list
テストケースをノードとして管理?する。
test_document
が一番トップの型みたいだ。
let rec count_test_nodes nodes count = match nodes with | [] -> count | TestCaseNode(_, _, _, _)::xs | TodoTestCaseNode(_, _, _, _, _)::xs -> count_test_nodes xs count + 1 | DiagnosticNode(_)::xs | PlanNode(_)::xs -> count_test_nodes xs count
関数 count_test_nodes
はノードの数を数える。
具体的には TestCaseNode
と TodoTestCaseNode
を数える。
let count_tests = function Document(nodes) -> count_test_nodes nodes 0
count_tests
は引数が test_document
だった時用の count_test_nodes
だ。
function Document(nodes) ->
は Warning を発生させる。
この Warning をどうやって回避すれば良いのかは不明である。
let count_test_failures = function Document(nodes) -> let rec loop nodes count = match nodes with | [] -> count | TestCaseNode(Ok, _, _, _)::xs | TodoTestCaseNode(Ok, _, _, _, _)::xs | DiagnosticNode(_)::xs | PlanNode(_)::xs -> loop xs count | TestCaseNode(NotOk, _, _, _)::xs | TodoTestCaseNode(NotOk, _, _, _, _)::xs -> loop xs count + 1 in loop nodes 0
関数 count_test_failures
は指定されたノードリストの中から失敗したノードの数を数える。
書いたのは ここ に置いとく。