2012/02/22 21:14:44
spawnとexecの違いがわからんのでちょっと調べた。
Difference between spawn and exec of Node.js child_process
spawnはストリームをexecはバッファーを返す
で、Node.jsのドキュメントを読んでて
spawnをつかった 'ps ax | grep ssh' の例が書いてあったので、これをcoffeescriptで書いた。
ターミナルで普通に動くのでvowsでテストしたら、callbackが返ってくる前に変なオブジェクトが返ってきてなんじゃこりゃ?と。
coffeescriptをjavascriptにコンパイルして読んだら、変なとこにreturnが挿入されてたのであちこちにreturnを入れて勝手にreturnされないようにした。
psax.coffee
util = require('util')
spawn = require('child_process').spawn
psax = (callback) ->
ps = spawn('ps', ['ax'])
grep = spawn('grep', ['ssh'])
d = ""
ps.stdout.on 'data', (data) -> grep.stdin.write(data); return
ps.stderr.on 'data', (data) -> console.log('ps stderr: ' + data); return
ps.on 'exit', (code) ->
console.log('ps process exited with code ' + code) if code isnt 0
grep.stdin.end(); return
grep.stdout.on 'data', (data) -> d += data; return
grep.stderr.on 'data', (data) -> console.log('grep stderr: ' + data); return
grep.on 'exit', (code) ->
console.log('grep process exited with code ' + code) if code isnt 0
return
grep.stdout.on 'end', ->
callback(null, d); return
return
exports.psax = psax
returnを入れて最後に評価した式がかえらなくてしなくていいような記法は用意されてないんだろうか?
>>なんかモナドっぽくて素敵じゃないか。
vowsのテスト。宣言(文字列)の書き方のお作法がまだよくわかってない。should beとかshoud haveはわかるんだけど、whenとかAfterとか使い分けってどうなってんの?
そういうお作法が書いてあるサイトないかなぁ。
vows = require('vows')
assert = require('assert')
sp = require('./psax')
psax = sp.psax
vows.describe('Psax').addBatch({
'A psax': {
topic: -> psax
'should be a function': (px) ->
assert.equal(typeof px, "function")
'After psax function called': {
topic: (psax) -> psax(this.callback)
'callback should return a result': (err,result) ->
assert.isString(result)
}
}
}).export(module)
2012/02/22 04:35:35
紆余曲折の末Yahoo! APIに落ち着いた。
http = require('http')
querystring = require('querystring')
qst = querystring.stringify({
appid: '################',
sentence: 'もももすももももものうち',
results: 'ma'
})
options = {
host: 'jlp.yahooapis.jp',
port: 80,
path: '/MAService/V1/parse?' + qst
};
http.get(options,
(res) ->
body = ""
res.on('data', (data) -> body += data)
res.on('end', -> console.log(body))
).on('error',
(e) -> console.log("Got error: " + e.message)
)
追記12.02.22
結果がXMLで返ってくるのでパースしないといけないが、node.js で libxml を使うにはどのライブラリをつかうべきかというエントリを参考にしてlibxml-to-jsを選択。
http = require('http')
querystring = require('querystring')
parser = require('libxml-to-js')
qst = querystring.stringify({
appid: '######',
sentence: 'あたしはプログラムの女の子です',
results: 'ma'
})
options = {
host: 'jlp.yahooapis.jp',
port: 80,
path: '/MAService/V1/parse?' + qst
};
http.get(options,
(res) ->
body = ""
res.on('data', (data) -> body += data)
res.on('end', -> parser(body, (err, result) -> console.log(result.ma_result.word_list)))
).on('error',
(e) -> console.log("Got error: " + e.message)
)
結果
{ word:
[ { surface: 'あたし', reading: 'あたし', pos: '名詞' },
{ surface: 'は', reading: 'は', pos: '助詞' },
{ surface: 'プログラム', reading: 'ぷろぐらむ', pos: '名詞' },
{ surface: 'の', reading: 'の', pos: '助詞' },
{ surface: '女の子', reading: 'おんなのこ', pos: '名詞' },
{ surface: 'です', reading: 'です', pos: '助動詞' } ] }
2012/02/13 05:58:59
exports.Test = class Test
method_a: () -> method_b()
method_b: () -> console.log("method b")
がmethod_bが見つからないっていうエラーが出た。
coffee> Test = require("./test").Test
[Function: Test]
coffee> t = new Test
{}
coffee> t.method_a()
ReferenceError: method_b is not defined
小一時間悩んだ挙句@が必要なことに気づいた
exports.Test = class Test
method_a: () -> @method_b()
method_b: () -> console.log("method b")
2012/02/07 21:19:20
最近見かけたsofで役に立ったもの
CoffeeScriptでループさせるには
while文かloop文。個人的にはloopのほうが好みかな
ExpressのdynamicHelpersの 使いどころ
Node.jsのnextTickを理解する
これはかなり良かった。理解が深まった。
スマイルプリキュア
5人も覚えられない
2012/01/27 19:02:15
去年、恋するプログラムをJavascriptで書いていこうとしたんだけど、Canvasとかわからなくて4章くらいで放置してた。
その間にHTML Canvas読んだり、Node.jsもわかってきたので再開しようかなと。vowsも使ってみたいし。
で、このやつをCoffeeScriptに書きなおした
class Responder
constructor: (@name) ->
response: (input) -> input + 'ってなに?'
class Unmo
constructor: (@name) ->
@responder = new Responder('what')
@responder_name = @responder.name
dialogue: (input) -> @responder.response(input)
u = new Unmo('proto')
console.log(u.dialogue('マックロシーベルト'))
動かしてみる
$ coffee test.coffee
マックロシーベルトってなに?
2012/01/26 20:57:53
CoffeeScriptでテストをできるライブラリを探していたらvowsで出来ることを知った。
vows = require 'vows'
assert = require 'assert'
vows
.describe('Division by zero')
.addBatch
'when dividing a number by zero':
topic: -> 42/ 0
'we get Infinity': (topic) ->
assert.equal topic, Infinity
'but when dividing zero by zero':
topic: -> 0 / 0
'we get a value which':
'is not a number': (topic) ->
assert.isNaN topic
'is not equal to itself': (topic) ->
assert.notEqual topic, topic
.export(module)
これをvows --specすると

かなり良い感じですね。
2012/01/24 19:44:03
sof見てたら「xxx.jsっていうjavascriptをCoffeeScriptにしたいんだけど」「js2coffee使え」っていう問答があったので、使ってみた。
$ npm install -g js2coffee
$ express testapp
$ cd testapp
$ js2coffee app.js
で、無事に変換された
app = module.exports = express.createServer()
app.configure ->
app.set "views", __dirname + "/views"
app.set "view engine", "jade"
app.use express.bodyParser()
app.use express.methodOverride()
app.use app.router
app.use express.static(__dirname + "/public")
app.configure "development", ->
app.use express.errorHandler(
dumpExceptions: true
showStack: true
)
app.configure "production", ->
app.use express.errorHandler()
app.get "/", routes.index
app.listen 3000
console.log "Express server listening on port %d in %s mode", app.address().port, app.settings.env
となると、srcフォルダを掘ってそこに.coffeeを入れて、libにコンパイルしたjavascriptを生成するようなCakefieを書けばいいような気がするが、nodeunitのテスト入れたいばあいどうすればいいのかな?
perlみたいに
ってやれればいいんだが。
CoffeeScript自体のソースコードを読むのがいい気がしているが、他にベストプラクティス的なものはあるんだろうか?
2012/01/17 19:12:36
Spineっていうクライアント側でMVCを実現するWebフレームワークが面白かったので、そのライブラリの作者が書いたJavascript Web Applicationsっていう本を読んでいる。
先週末の温泉旅行と、今日の出張の新幹線の行き帰りで7章まで読んだので感想をちょっと書いておくが、サイ本に対してフクロウ本って言われるようになるのかなぁって感じの内容だと思うがどうなんだろう。
手を動かしながら学ぶという本ではなくて、クライアント側でMVCを実現するにはどうしたらよいかという方法論を学ぶ本なので、写経して覚えるというより、自分の中の知識を統合して一つ上のレベルに昇格する感じ。
- Spineを一通り使えるようになっていること
- JGPの内容を理解していること
- Javascriptパターンを理解していること
は必須な感じ。副題がjQuery developer's Guide to Moving State to the Clientと書いてあるんだけどjQueryの知識はあんまり必要でなくて、ググッて理解できるか、該当するソースコードを読めればOKだと思います。それよりもなぜそういう実装にしないといけないのか?っていうことを考えることを求められますね。
2012/01/14 13:14:48
javascriptパターンの7章のサンプルをCoffeeScriptでかきなおしてみた。オリジナルのコードはこれ。
コンソールログを開くと実行されていることがわかる。
CoffeeScriptで書きなおしたほうの実行結果。ターミナルで確認できるので楽ですね。
$ coffee pubsub.coffee
Just read big news today
Just read big news today
Just read big news today
About to fall asleep reading this interesting analysis
コード。デバッグ用にprintSubscribersっていうメソッドを付けた。それからオリジナルコードはmix-inしていたので最初はfor-of文でそのとおりに書いたんだけど、for-of文でtypeof methodするとfunctionじゃなくてstringが返ってくるのが嫌だったので、継承を使って実装してみた。
class Publisher
constructor: ->
@subscribers = { any:[] }
subscribe: (fn, type) ->
type = type or 'any'
@subscribers[type] = [] unless @subscribers[type]?
@subscribers[type].push(fn)
unsubscribe: (fn, type) -> @visitSubscriers('unsubscribe', fn, type)
publish: (publication, type) -> @visitSubscriers('publish', publication, type)
visitSubscriers: (action, arg, type) ->
pubtype = type or 'any'
subscribers = @subscribers[pubtype]
for subscribe,i in @subscribers[pubtype]
switch action
when 'publish' then subscribe(arg)
else @subscribers[pubtype].splice(i,1) if subscribe is arg
printSubscribers: -> console.log(@subscribers)
class Paper extends Publisher
daily: => @publish('big news today')
monthly: => @publish('interesting analysis','monthly')
class Subscriber
drinkcoffee: (paper) -> console.log('Just read '+ paper)
sundayPreNap: (paper) -> console.log('About to fall asleep reading this '+ paper)
paper = new Paper
joe = new Subscriber
paper.subscribe(joe.drinkcoffee)
paper.subscribe(joe.sundayPreNap, 'monthly')
#paper.printSubscribers()
paper.daily()
paper.daily()
paper.daily()
paper.monthly()
この本どうなんだろう、一度読んでおくべきなのかな?