この記事は なんか書く太郎|GWアドベントカレンダー 4日目の記事です。
昨日は @yusaka39 さんの Kotlin Serialization + Jersey で RESTful API でした。
前置き
サーバサイドエンジニアなのですが
少し前からJavaScriptを学習しています。
先日JavaScriptのIteratorを学習したのでGeneratorで少し遊ぼうと思っています。
簡単なチャットボットを作ろうと思ったのですが家族でホルモンを食べて酔っ払った状態で先程帰宅して寄稿まで時間がないので大した内容を書けそうにありません。
localのnode.jsで用意したGeneratorのファイルをimportして遊びます。
好きなジャンルとエリアを指定して、Rettyさんの検索URLを生成して返すというシンプルなアプリケーションをイメージしています。
exports.default = () => {
function* gen() {
console.log('好きなジャンルはなんですか?')
let cat = yield 'start'
if(cat.match(/.*焼肉.*/)) {
console.log('やはり' + cat + 'ですね')
} else {
console.log('う~ん焼肉以外ですね')
console.log('焼肉を選んでください')
}
let area = yield '何駅でお探しですか?'
console.log(area + 'でお探しですね。URLを発行する場合は"y"と入力してください')
let url = `https://retty.me/restaurant-search/search-result/?latlng=35.778026%2C139.720928&free_word_area=${area}&station_id=2017&free_word_category=${cat}&category_type=310`
const answer = yield url
if(answer == 'y') {
console.log(`${area}、${cat}のおすすめのお店はこちらです`)
console.log(url)
}
}
return gen()
}
Generatorを利用した簡易的な対話側のコードができました。
それでは遊んでいこうと思います。
$ node
> const gen = require('./gen')
undefined
>
> c = gen.default()
Object [Generator] {}
>
> c.next()
好きなジャンルはなんですか?
{ value: 'start', done: false }
>
> c.next('焼肉')
やはり焼肉ですね
{ value: '何駅でお探しですか?', done: false }
>
> c.next('新宿駅')
新宿駅でお探しですね。URLを発行する場合は"y"と入力してください
{ value:
'https://retty.me/restaurant-search/search-result/?latlng=35.778026%2C139.720928&free_word_area=新宿駅&station_id=1376&free_word_category=焼肉ですかね&category_type=310',
done: false }
>
> c.next('y')
新宿駅、焼肉のおすすめのお店はこちらです
https://retty.me/restaurant-search/search-result/?latlng=35.778026%2C139.720928&free_word_area=新宿駅&station_id=1376&free_word_category=焼肉&category_type=310
{ value: undefined, done: true }
>
これをUIからの入力操作でコントロールすればもうちょっと楽しそう。
焼肉以外も検索できるようにしたいですね。
Rettyのstation_idの辞書、category_typeの辞書があればmatchしてURLを変化させられます。
言語の曖昧さを吸収する処理は難しいですが。
終わりに
再帰処理などでメモリを捨てながら使うイメージが強いIterator/Generatorですが、対話型の処理にGeneratorを活用することも頑張ればできるという事例でした。Generator使わなくてもできるじゃんというご意見は置いといて。
よいGWをお過ごしください。
明日は @flum1025 さんの Dockerでインターネット越しにネットワークを組む です。