2011年12月16日金曜日

node.js + socket.io + Arduinoでイイネ!



eXtreme Hagoで使われていた、リアルタイムに「いいね」と出すあのシステムをパクりました。


node.js + CoffeeScript + express + node-arduino + MongoDBで出来てます。


デモ動画



動機


ITfrogsとLexuesAcademyの懇親会でくまさんがいいねと同じの200分で作った!と言ってたので僕も作りたくなった。


これが@さんがつくったやつ。


higumachan/iine ? GitHub


本家のイイネに加え、グラフ機能つき。


開始時間と終了時間にぽちっとボタン押すとグラフが表示され、どこで盛り上がったか一目瞭然。


こんなすごいの「200分で作った」なんて言われたら僕も作りたくなっちゃうでしょ!!


僕が何か1つ機能を付け加えるなら何がいいか?


「そうだ、リアルにボタン押す機能でも作るか」


出来ました。


f:id:h6n:20111216035307j:image:w360


ソースコード


hanachin/iine_duino ? GitHub


※何分で出来たかは秘密です


解説


僕はCoffeeScriptにハマっています。ちゃんと使ってみたい。


CoffeeScriptが書ければJavaScriptも書ける。


JavaScriptが書ければnode.jsが使える。


なので、CoffeeScript + node.jsで作成することに決めました。


ウェブサイトを表示する

ウェブ側はexpressを使って表示することにした。


理由:




  • 直接書くのは多分面倒

  • Sinatra-likeで学習コストが低そう

  • 持ってる本(パーフェクトJavaScript)に例がのってる


本のサンプルを動かしながら使い方を覚えさくっと開発環境を整える。


リアルタイムにイイネを出すために

Nodeが使えればsocket.ioが使える!!


ということでsocket.io使えば楽勝でした。


ただし実際にコード書くよりも使い方を調べる方が時間かかった。


socket.ioを使う理由:




  • リアルタイムに通信したいから

  • 自分でリアルタイムに通信出来るように一から書くより簡単、確実、便利、安心

  • 使ってみたかった


グラフを表示するために

くまさんはjqplotというライブラリを使っていたので僕もそれを使うことに。


グラフを表示するためには記録が必要、なのでMongoDBを使うことにしました。


理由:




  • RDBを設定するのが面倒だった

  • 既にmongooseというライブラリがある

  • 本に例が載ってる


イイネが押された時刻だけを記録するシンプルなデータベースです。


まず、開始時刻と終了時刻を含んだURLにアクセスすると、その間のイイネを集計してJSONで返すようなAPIを作った。


あとはグラフを表示する側からそれを叩いて、jqplotに渡すだけ。jqplot便利ですね。


リアルにボタンを押すために

ボタンをArduino経由でPCに接続しようと考えた。


押せればなんでもいいので100円ショップでプッシュライトボタンを買います。


Arduinoとnode.jsをつなぐにはnode-arduinoを使います。


普通にnpm install arduinoで入れると、digitalRead(入力)が使えなくてハマってました。


Forkされてるこちらのリポジトリを使いましょう。


hapticdata/node-arduino ? GitHub


後は、ボタンを分解してスイッチのところにつなぐだけ。簡単ですね。


Tips等



  • Guardを使うとCoffeeScriptを勝手にコンパイルしてくれる。coffee -wcでやるよりも便利。

  • node-devを使うとJavaScriptファイルが更新されると自動でサーバーを再起動してくれて楽。

  • プッシュライトはLEDが3つついてるんだけど、どうやって光らせるか誰か教えてください。(Arduinoじゃ電流足りないよね?)


反省点


3つあげると




  • コード書くのに時間をかけすぎた

  • ブログの解説がざっくりすぎる

  • ブログ書くのも旬なうちじゃないと書けない(なので早く製品を作ろう)


まとめ




  • CoffeeScriptでイイネシステムが書けた。

  • expressを使うと簡単にウェブアプリが書ける。

  • socket.io使えばリアルタイムに通信が出来る。


    • どうやって通信するか考えなくて済むのでリアルタイム性の高いものがすぐ作れる。



  • jqplotは見栄えのいいグラフをさっと作れる。

  • node-arduinoを使えばnode.jsとArduinoを連携出来る。


    • ソフトウェアだけでは出来ないことが出来るようになるかも。




オリジナル版と、くまさんの作った奴がなかったら作れなかった。ありがとうございます。


作ってる途中、失敗がいくつもあったけど最終的にボタン押して出来るようになると超楽しかった。


もっと電子工作、はんだづけやってみたい!


もっと聞きたい事、詳しく書いてほしい事があれば@までお願いします。





2011年12月13日火曜日

SimpleTimeKeeperにURLでタイマーの時間を指定出来る機能を追加してpull requestおくったった



SimpleTimeKeeperという便利なタイマーがあります。


SimpleTimeKeeper


シンプルで見やすくてとってもべんり。プレゼンの時に重宝します。


その、SimpleTimeKeeperに、タイマーの時間をURLで設定出来る機能を付け加えてみた。


URLの末尾に#10:20や?10:30や#10-20や#10m20sとつけるだけで設定出来るよ!


実装


location.searchかlocation.hashを数字ごとに区切って、前から3つとってくる感じになってます。


最後にreverseしてるのは、10:20みたいに、hours, minutes, secondsを全部指定してないときに都合がいいからです。



time = (location.search || location.hash).split(/[^0-9]/).filter(function (x) { return x !== ""; }).slice(0, 3).map(function (x) { return parseInt(x, 10); }).reverse();
// Set Timer
$('#hours').val(time[2] || 0);
$('#minutes').val(time[1] || 0);
$('#seconds').val(time[0] || 10);


まとめ




  • SimpleTimeKeeperはシンプルだから機能を追加するのもらくちん。

  • もっと追加したい機能があるけど、追加するにしても、なるべくシンプルにいきたい。

  • 僕はforEachやfilterやmap等、enumerateするメソッドを続けて書く事が好きだということに気づきました。


こないだもこんなの書いてたし。



urls = tweets.select{|t|
not t.attrs["entities"].empty?
}.select{|t|
t.attrs["entities"]["urls"]
}.map{|t|
t.attrs["entities"]["urls"].map{|u| u["expanded_url"]}
}.inject([]) {|result, urls|
result + urls
}.select{|u|
DB[:urls].where(:url => u).count.zero?
}.uniq





カップ麺用タイマーアプリ「QuickNoodleTimer」



作りました。


hanachin/qnoodle ? GitHub


起動した瞬間から3分間カウントが始まります。


タイマーのスタートボタン押す必要なし。


Homeボタンを押して別のアプリを開いてても安心、3分たつとToastメッセージと(ちょっと小さい)音とバイブで知らせてくれます。


野良アプリですけど、インストールはこちらから


QNoodle.apk





ホモスレbotを書きました。



ホモスレのURLをツイートするホモスレbotを書きました。


Twitter

ホモスレbot


ソースコード(ライセンスはWTFPL)

hanachin/homosure ? GitHub


要求


最近はホモスレ多いですよね。1日に何本も立ってる気がします。


僕が欲しかったもの



  • 手動でホモスレ検索する手間が省ける

  • 面白いホモスレならTwitterで誰かがつぶやいてくれているはず

  • 2chの生のホモスレではなくまとめが見れればよい

  • 既に見た事あるスレは見なくてもいい

  • なるべくホモスレでの検索結果を汚さない


欲しかったので作る、いつもの流れですね。


実装


何度か使ってなれているので、Twitterのgemを使っています。


Twitterの「ホモスレ」の検索結果からURLを抽出し、DBにデータを蓄積しツイートするようになってます。


既にツイートしたことのあるURLはツイートしないようになってます。


一旦Mechanizeで実際にアクセスすることで、リダイレクト後のURLを取得するようになっています。(なっているはずです、多分)


実際にアクセスする前のURLと、実際にアクセスしたURLが違う場合(リダイレクトなど)データベースで、リダイレクト後のページとひもづけてます。


これから機能を追加するなら




  • Twitterでそのホモスレの検索結果の隆盛等をグラフで表示する

  • URLリダイレクタを挟んでクリック数等の情報を取得する

  • 【今日のホモスレ】や【お勧めのホモスレ】等、既にDBにあるホモスレからリコメンドする

  • ページの内容からホモスレ度を判定する

  • 蓄積したホモスレのURLを元に、ホモスレを掲載してるまとめブログの一覧を作り、RSS等からもホモスレ情報を集める


まとめ


前から欲しいなーと思ってたので作りました。快適な生活に一歩近づきましたね。


もっと需要の高そうな別のワードに対するbotを作成するときに役立つかもしれません。


ホモスレbot作った話をブログに公開することで更にアレなものを作っても公開出来る謎の自信がつきました。





2011年12月10日土曜日

最近.zshrcに追記したgitの設定



とりあえず僕が使いそうなものだけ。


便利そうなのあったら追記しようと思う



# aliases
alias g='git'
alias ga='git add'
alias gb='git branch'
alias gc='git checkout'
alias gco='git commit'
alias gd='git diff'
alias gp='git push'
alias gs='git status'
alias gh='git push heroku master'





Guard + Powで快適Sinatra開発



Sinatraを使ってWebアプリケーションを作る際、Sinatraを手動で何度も再起動するのは面倒くさくないですか?


そんなときはGuardとPowを使えばSinatraのファイルを書き換え保存するだけで自動的に再起動させることが可能です。


これでテンポよく快適に開発出来ます。


Powの導入


~/.pow/以下にRackアプリのディレクトリへのシンボリックリンクをはるだけで、http://ほにゃらら.dev/でそのアプリにアクセス出来るようになります。


Homebrewを使っている場合は



% brew install pow


で導入出来ます。(多分)


僕はbrewを使わずに入れました。Powにはnode.jsが必要です。


僕はnvmを使ってnode.jsインストールしてPowのサイトに書かれたコマンドを実行してインストールしました。お好きな方で。


参考:Node.js 入門


参考:Pow: Zero-configuration Rack server for Mac OS X


Powderの導入


Powを更に便利に使うためにPowderをインストールします。



% gem install powder


で入ります。


参考:Pow使うならPowder入れておくだァーッ! - Meltdown Countdown


Guardの導入


Guardを使えばファイルが変更されたら自動で何かすることが出来ます。


自動で何をするのかをGuardfileに書きます。


bundlerやcucumberなど様々なツールに対応しています。(参考:List of available Guards ? guard/guard Wiki ? GitHub


guard-powを使えばSinatraのファイルをいじったら再起動、といったことが簡単に出来ます。



% gem install guard-pow


参考:Guard::PowでPowを更に快適に使う | ひげろぐ


試しにSinatraアプリを作ってみる


コマンドログ


Nil% mkdir hello
Nil% cd hello
Nil% cat > web.rb
require 'sinatra'
get '/' do
'Hello world!'
end
Nil% cat > config.ru
require "./web.rb"
run Sinatra::Application
Nil% cat > Guardfile
guard 'pow' do
watch('web.rb')
end
Nil% cat > .rvmrc
use 1.9.2
Nil% powder link
Your application is now available at http://hello.dev/
Nil% guard
Guard is now watching at '/Users/sei/hello'


ソースコード


この状態でweb.rbを書き換えると



Pow restarted.


と表示され、無事再起動していることが確認できます。


ハマったところなど




  • 僕はrvmでRubyを管理してるのですが、.rvmrcの中で使うRubyのバージョンを指定するのを忘れて怒られました。

  • guard pow initでGuardfileを生成する方が楽かも。(Railsアプリ等の場合)

  • 僕の場合、Sinatraのアプリの中に直接日本語を書いてたりするのでconfig.ruの先頭に1行これを付け加えてます。



# -*- coding: utf-8 -*-


まとめ


この記事はざっくりすぎるので参考リンクを読んだ方が詳しく書いてます。


ざっくりまとめると




  • Powを使うと~/.pow/シンボリックリンクはるだけでRackアプリが動く

  • Powderを使うとシンボリックリンクはるのや、Powに関わるあれやこれやをやってくれる

  • Guardを使うとPowで動いてるRackアプリを自動で再起動出来る


以上です。





Chromeのconsole.logの謎



この記事を読んで、Chromeのconsole.logの動きが謎すぎる気がして確認してみました。


CoffeeScriptで、newするときのプロパティ変数の初期化ってどーなってんの? - uzullaがブログ


検証


ソースコード


var a = [];

a.push('A');
console.log(a);

a.push('A');
console.log(a);


これをChromeのDeveloper toolのコンソールで実行してみました。


期待する出力


["A"]
["A", "A"]


実際の出力


["A", "A"]
["A", "A"]


調べてみた


console.log lazy等でググるとStackoverflow等のサイトがでてきた。


Is Chrome's JavaScript console lazy about evaluating arrays? - Stack Overflow


javascript - Bizarre console.log behaviour in Chrome Developer Tools - Stack Overflow


Bug 35801 – console.log object maps are read when you open the treeview on the console, not when they’re output in the console


なるほど。Webkit特有なのかもしれません。


console.logにオブジェクトを渡すと、console.logはそのオブジェクトの内容を出力します。


console.logが出力する準備をしている間にそのオブジェクトに変更を加えると変更後のオブジェクトの内容が出力されると。


シンプルな解決方法として




  • JSON.stringify

  • toString

  • slice (配列の場合)


等のメソッドや関数を使って別のオブジェクトを作成してから渡す方法が挙げられてますね。


ちなみに



Coffeescriptのクラスのプロパティ変数って、初期化が必須なの?(;´Д`)
コンストラクタで宣言しなおさないと、暗黙のウチに共有されちゃうの?
そういうもんなの??

JavaScriptのprototype継承ですね。



class Chain
queue: []
test: -> @queue.push "A"




var Chain;
Chain = (function() {
function Chain() {}
Chain.prototype.queue = [];
Chain.prototype.test = function() {
return this.queue.push("A");
};
return Chain;
})();


JavaScriptになるとこうなっています。


Chainクラスはprototypeというオブジェクトを持っています。(以下prototypeオブジェクト)


CoffeeScriptのクラスのメソッド等はこのprototypeオブジェクトのプロパティに定義されます。


Chainクラスのインスタンスはprototypeオブジェクトへの参照を持っています。


Chainクラスのインスタンスからqueueプロパティにアクセスするとき




  1. まずインスタンス自身がqueueプロパティを持っていないか調べる

  2. 持っていなければクラスのprototypeオブジェクトにqueueがないか調べる。

  3. クラスのprototypeオブジェクトにもqueueプロパティがなければ更に継承元のクラスを辿って行く


という感じになってます。


インスタンス自身がプロパティを持っているかどうか調べるためにはhasOwnPropertyを使います。



ソースコード



class Chain
queue: []
test: -> @queue.push "A"

c = new Chain
console.log "before c.queue = []"
console.log c.hasOwnProperty "queue"

c.queue = []

console.log "after c.queue = []"
console.log c.hasOwnProperty "queue"


実行結果


before c.queue = []
false
after c.queue = []
true


queueプロパティに配列を代入するまで、Chainクラスのインスタンスは自分自身のqueueプロパティを持ちません。


そのため、全てのインスタンスがChainクラスのprototypeオブジェクトのqueueプロパティを参照しています。


なのでtestメソッドの中でthis.queue.push("A")を呼び出すと、Chainクラスのprototypeオブジェクトのqueueプロパティが変更されるわけです。


こう書くとなおるわけ



ソースコード



class Chain
constructor: -> @queue = []

console.log "c = new Chain"
c = new Chain
console.log "c.hasOwnProperty 'queue': #{c.hasOwnProperty 'queue'}"


JavaScriptになると



var Chain, c;
Chain = (function() {
function Chain() {
this.queue = [];
}
return Chain;
})();

console.log("c = new Chain");
c = new Chain;
console.log("c.hasOwnProperty 'queue': " + (c.hasOwnProperty('queue')));


実行結果


c = new Chain
c.hasOwnProperty 'queue': true


コンストラクタの中で以下のコードを呼び出すことで、インスタンス自身のプロパティとしてqueueを定義しています。



this.queue = [];


インスタンス自身のプロパティなので、ほかのインスタンスのqueueを変更しても、関係ない。


そんな感じ。


まとめ




  • Webkitのconsole.logはオブジェクトが表示されるまでにディレイがあって、その途中でオブジェクトの中身を変更すると、変更後の内容が出力される

  • CoffeeScriptのクラスの仕組みについて知るためにはJavaScriptのプロトタイプチェーン等に関する知識が必要。


JavaScriptについて勉強するにはパーフェクトJavaScriptがお勧めです。



パーフェクトJavaScript (PERFECT SERIES 4)

パーフェクトJavaScript (PERFECT SERIES 4)










2011年12月7日水曜日

EmacsからnodeやブラウザでCoffeeScriptを動かす



前に書いたJavaScriptの開発環境を整えるついでにCoffeeScriptの環境が整います。


EmacsでJavaScriptの環境を整えたい - はなちん C-x C-c


swank-jsの導入


ivan4thさんのswank-jsを使うとEmacsからNodeやブラウザにつないでJavaScriptを実行できます。


JavaScriptならChromeの開発者ツールやFirebugでも出来ますが、やはりEmacs上で出来ると幸せです。(そのまま保存出来るし)


僕はswank-jsにCoffeeScript用の機能をいくつか付け加えました。


GitHubに置いてあるので、そこから導入します。


hanachin/swank-js ? GitHub


swank-js導入手順


ほとんど深町さんのこの記事と一緒です。


Emacsからnode.jsやChromeとSocket通信 - 八発白中


違うところだけ、説明します。


0.swank-jsのダウンロード

CoffeeScript用に改造してある僕のリポジトリから落とします。



% git clone git@github.com:hanachin/swank-js.git


1.nodeをインストールします

自分はここを参考にしました。


no title


3.SLIMEをインストール

僕の環境だと最新のSLIMEだとswank-jsがうまく動かなかったので、LispBox同梱の物を使いました。


Lispbox


中に入っているslimeのフォルダを、Emacsのロードパスの通っている場所へ置きます。


自分の場合だと~/.emacs.d/elisp/あたりに入れてます。


5.emacsに設定を追記

もとの記事のjs2-mode-hookに加えて、coffee-mode-hookの設定を.emacsに追記します。



(add-hook 'coffee-mode-hook
(lambda ()
(slime-js-minor-mode 1)))


EmacsからCoffeeScriptを使う


swank-jsのディレクトリで以下のコマンドを実行し、swank-jsのサーバーを立てます。



% node swank


EmacsでM-x slime-connect、接続。(ここでslimeとswank-jsのバージョンが違う等のメッセージが出るが気にしない)


ここまではJavaScriptと同じです。


slime-repl JSのバッファーで,select-remoteと入力して、CoffeeScript/directを選びます。


あとはJavaScriptと同じ感覚でCoffeeScriptを入力して実行出来ます。とっても簡単ですね。


EmacsからブラウザのREPLにアクセスしCoffeeScriptを使う


次のブックマークレットを、CoffeeScript使ってattachしたいページで実行します。


Attach Swank Coffee


後はslime-reple JSの画面で,select-remoteでCoffeeScript Browserと書いてるやつを選べばおk


f:id:h6n:20111208014158p:image


このように、Emacsで書いたCoffeeScriptをブラウザで実行できます。


また、coffee-modeで範囲を選択して、C-c C-rで実行することもできます。


まとめ




  • 最初はslime-js.elの方をいじって、elisp側でCoffeeScript->JavaScriptの変換かけようとしていたが面倒だった

  • swank-handlerのRemoteを継承するクラスを作ってevaluateメソッドをオーバーライドし、そこで実行前に変換をかければよい

  • そのクラスをswank.jsの中で使うようにする

  • 別のaltJS、JavaScriptにコンパイルされる言語(Cocoなど)をEmacsから叩きたいときも同じ感じでいけるかも。


という感じ。


CoffeeScriptの問題として、コンパイル後のJavaScriptコードを実行中にエラーがおき、エラー行が表示されても、元々のCoffeeScriptの何行目に対応するのか分からないといったところがあります。


これについてはこちらのスレッドで意見がかわされてるようです。


Issue #558: line number mapping for debug ? jashkenas/coffee-script ? GitHub


まぁ僕はとりあえずCoffeeScriptをEmacsから実行できる環境が整ったので満足です。


Emacs使いでCoffeeScript使いで興味を持ってくださった方は是非試されてみてください。


フィードバックは@まで。





EmacsでCoffeeScriptの環境を整えたい



flymakeでエラーを表示したい


いちいちコンパイルしてエラーが出てるか確認するのは面倒。

ここを参考にflymakeの設定をする。

coffeescriptでflymakeする - antipop

EmacsからCoffeeScriptを評価して、結果が見たい


regionを選択してえばるとChrome Developer Toolsに表示するところまで出来ました。

追記

こちらの方でより良い方法を解説しています。

EmacsからnodeやブラウザでCoffeeScriptを動かす - はなちん C-x C-c

1.まずはここを参考にJavaScriptの開発環境を整えます。

EmacsでJavaScriptの環境を整えたい - はなちん C-x C-c

2.CoffeeScriptをえばるためのslime-coffee.elを導入する

ロードパスの通った所に置いてください。

eval region, coffee-script — Gist

後は、JavaScriptと同じようにnode swankでswankサーバーを立ち上げ、ブラウザにブックマークレット使ってattachして、範囲を選んでC-c C-rで、えばれます。

デモ動画




next


もっといい方法を思いついたのでこれから実装




2011年12月6日火曜日

僕のブックマークの可視化



僕のはてなブックマークの、1月頃から10月の末あたりまでの、タグ付けの様子を可視化してみました。



タグごとに円で表示されています。


いっぱいブックマークされたタグは大きめに表示されます。


時間がたつにつれて円がだんだん小さくなります。





2011年12月5日月曜日

EmacsでJavaScriptの環境を整えたい



とりあえずここを参考にEmacsからChromeやNodeを叩けるようになりました。


Emacsからnode.jsやChromeとSocket通信 - 八発白中


ひっかかった点


swank-jsは更新されてるようで、本家のものを使うことでいけた。


僕の環境だと問題になったのはSLIME.


最新のSLIMEを使うと、slime-connectした際にcoding-systemが云々とエラーメッセージが出てうまく動かなかった。


昔のやつを落としてきて、うまく動いた。


js2-mode


js2-mode - 紫藤のWiki


ここを参考にしながら、Google Codeから最新版を落としてきて



% cp ~/Downloads/js2-20090723b.el ~/.emacs.d/elisp/js2.el
% emacs -batch -f batch-byte-compile ~/.emacs.d/elisp/js2.el

して、init.elに



(autoload 'js2-mode "js2" nil t)
(add-to-list 'auto-mode-alist '("\\.js$" . js2-mode))

を書き加えていけた。(~/.emacs.d/elisp/にパスを通してないとだめ)





2011年12月1日木曜日

CoffeeScriptでHQ9F+のインタプリタ書いた。



Esoteric Language - ネットワーク?なにそれおいしいの?


を見て書こうとおもったので、書いた!



インスタンス変数のデフォルト引数でハマりそうなところ



out = (x) -> console.log x
class Foo
constructor: (@out = out) ->


このようなCoffeeScriptは



var Foo, out;

out = function(x) {
return console.log(x);
};

Foo = (function() {

function Foo(out) {
this.out = out != null ? out : out;
}

return Foo;

})();


このようにコンパイルされる。


デフォルト引数の値に、インスタンス変数と同じ名前の変数を渡すと、インスタンス変数の方で隠されてしまうので注意。





週末ものづくり講座で作ったもの学んだこと



10月・11月と、@さんの週末ものづくり講座を受講していました。


「早く実装し、早く評価し、早く学ぶ」、元々はLean Startup用の「早く失敗し早く学習する」を応用したものです。


このエントリはその最終課題です。


授業を終えて


僕は「僕でもイイモノつくれる」という自信がつきました。


授業終わってからも、もっと何かつくって勉強会で発表していきたいと思っています。


まずは僕がこの2ヶ月の授業でやってきたことをまとめます。


技術的なことはブログに書いてあるので参考リンクからどうぞ。




作ったものは8つ、未公開1つ、発表1回、脆弱性の届出6件です。


失敗や成功から得た知見はそれぞれのエントリにまとめてあります。


一番変わったのは多分メンタル。


授業を受けてから、勉強会ROM専門が勉強会で発表するように、作品が無かったのが8つも物が作れました。


自分でもびっくり。


「ものが作れる」という自信も出来たし、後は継続的にものをつくって、GitHubで公開して、ブログに書いて、勉強会に貢献しながら、もっといいものを作りたいと思っています。





2011年11月30日水曜日

Re: CoffeeScript if for of



こちらの記事を見て、4番目、5番目の案をあげてみました。


CoffeeScript if for of - すぱぶらのはてブロ



元記事はif elseとfor ofの組み合わせのようなので、existential operatorを使うのはコンテキストにあってない気もするけど、気にしないことにします。


僕が書くなら2行になるけど#5か、#1か#2が好きかも。





2011年11月29日火曜日

ギークハウス沖縄調べてみてちょっと気になる物件



ずらずらとあげて行きます。結構多い。


1.那覇市識名、5DK、4.5万円、一戸建て


理由



  • 安い

  • ぼろい

  • 少し歩けばバス停があり新都心・バスターミナル方面、また開南方面にもバスで行ける

  • 県立図書館や沖縄大学や看護大に近く図書館いっぱい利用出来そう


2.那覇市久米2、3SLDK、9万円、一戸建て


理由



  • 広い(LDK17)、他の部屋も広いしなんか螺旋階段付いとる。

  • バストイレが2つ付いてる

  • 駐車場が1台つく

  • ピアノ可ということで多少騒がしくても大丈夫そう


3.那覇市泉崎、3LDK、8.5万円


理由



  • 敷金・礼金無しなので初期費用が抑えられる

  • 駅まで徒歩2分、バスターミナルにも近く交通の便は最高

  • バストイレ別


4.那覇市久茂地、3LDK、6.9万円


理由



  • 美栄橋駅まで徒歩2分

  • 敷金・礼金なし

  • 6万9000円と比較的安いので3人でわると一人当たり2万3000円


5.那覇市前島、4LDK、10万円


理由



  • リビングが25畳ってめっちゃ広くないですか!

  • 4LDKだから一人増えても対応可能


疲れたのでざっとリンク


那覇市泉崎、3LDK、6万円、敷金なし、県庁近く


那覇市安里、3DK、6.3万円、安里駅まで徒歩1分


那覇市松尾、3LDK、6.3万円、敷金なし、リビング広い、市場近い


眺めが良さそう


雑感


やっぱり宜野湾の5LDK、6万のお部屋が魅力的に見える。


それぞれの個室に鍵も付いてるし、共有スペースも広いし。


交通の便的に考えて僕はちょっと辛いけど沖国大や琉大の人誘えば僕居なくても人数埋まりそうですね…


僕としてはバスターミナル近辺にバスまたはモノレールで通えるなら嬉しい。


徒歩で通えるなら学校や会社への交通費も浮くから嬉しいです。


@と職場近いからその付近におうちあれば楽かな、と思う。


あと初期費用押さえるなら敷金礼金無しの物件探すとか(あるいは交渉して無くしてもらえないかとか)


おまけ


初期費用も維持費も多分めっちゃ安い





2011年11月28日月曜日

RubyでシンプルなTwitterクライアント書いた



シンプルなTwitterクライアント書きました。


hanachin/tsurube ? GitHub


名前はTwitter×Ruby、ついるび、つるび、つるべ、ということでtsurube。


コマンドラインで動作するTwitterクライアントを30分くらいで作れるPythonはかっこいい - YAMAGUCHI::weblog


こちらの記事をを見てRubyでやってみたくなった。


「30分? よゆー」と思ってたけどずるずる時間かかって実装力の足りなさを痛感しました。


今のところ




  • tl タイムライン取得

  • tl 40 タイムライン取得(1-200の間で指定)

  • mentions, m メンション見る

  • login, l ログイン

  • exit, quit, q 終了

  • tw ついーと


あたりのコマンドは実装した。基本的なツイートする、TL見る、メンション見る、終了する。が実装出来たし満足。


config.ymlに認証情報を登録したらすぐ使えます。


困ったところ


コンソールの操作するgem使った事ない

カーソルキーの上押すと前のコマンドが見れたり、Emacsバインドで編集出来れば最高なんですが、そういう事が出来るgemを僕は知らない。


探そうと思ったけどHighLineで対処。


今度良さそうなgemをいくつか試しておこうと思う。


warning: regexp match /.../n against to UTF-8 string

日本語で発言するときにここのコードで「warning: regexp match /.../n against to UTF-8 string」が出た。


faraday/lib/faraday/utils.rb at master ? technoweenie/faraday ? GitHub


UTF-8の文字列に対してRegExpのオプションでnを渡して漢字コード無視ってるのが問題なよう。


エラーメッセージでググると同じ問題がいくつか出てきた。


FaradayのUtilsのescapeメソッドの中身をEscapeUtilsのescape_url使うようにして対処。


工夫したとこ


元ネタのライセンスが面白かったので同じものを採用。


参考:WTFPL - Wikipedia


ログインが必要な処理をブロックで渡して、ログインしてなかったらログインを促すメッセージをだしブロックを実行しない、ログインしていたらブロックを実行する。


という風に書いてみた。ブロック可愛いよブロック。





2011年11月25日金曜日

CoffeeScript×enchant.js、enchant.jsをCoffeeScriptで書く。



enchant.jsをCoffeeScriptで書直しました。


hanachin/enchant.js ? GitHub


enchant.coffeeというファイルがあるはずです。


サンプルはexample/action-coffee/とexample/action-coffee2/以下に入っています。


理由


僕はCoffeeScriptにハマっています。CoffeeScriptは美しいからです。


functionを書かなくていいし、全て式なのでreturnを書かなくていいし、後置でifが書けるし、デフォルト引数もあるし、内包表記が凄く便利だし、?オペレータもかなり便利です。


僕はenchant.jsにもハマっています。enchant.jsは素早くゲームが作れるし、スマートフォンでもサクサク動くし、書いていて楽しいから。


enchant.jsがCoffeeScriptで書けたらいいな… そう思ってた時期にHotRubyからenchant.jsを使う記事を読みました。


wise9 › Ruby on enchant.js / RubyでHTML5ゲームを作ってみる


その中にはこう書かれていました。



ならCoffeeScriptで書けばいいじゃん、という意見もあるだろうけど、ここでは聞かなかったことにする。

僕はCoffeeScriptで書けばいいじゃん、と思った。


思ったからには書かねばならない。情熱が覚めないうちに。


まだまだ全然CoffeeScriptらしく書けてませんが公開します。


ちなみにenchant.coffeeの行数は2295行、元のenchant.jsが2685行なので14.5%、390行程度ソースコードの行数が減りました。


サンプルのアクションゲーム


9leap : enchant.coffeeサンプル by hanachin_ - どこでも遊べる、投稿型ゲームサイト


メソッドをオーバーライドするだけで動作


9leap : enchant.coffeeサンプル2 by hanachin_ - どこでも遊べる、投稿型ゲームサイト


ソースコードはこんな感じ



enchant()

class Bear extends Sprite
constructor: (w, h, image) ->
super 32, 32
@image = Game.instance.assets[image]
@x = 0
@y = 0

enterframe: (e) ->
@x = @x + 1

game = new Game(320, 320)
game.fps = 24
game.preload('chara1.gif')

game.onload = ->
bear = new Bear(32, 32, "chara1.gif")
game.rootScene.addChild(bear)

game.start()


もちろんenterframeだけでなく他のイベントにも対応しています。


実装について


全体的に

不要なfunctionを置換したりインデントを揃えるので時間がかかった。


メソッドのオーバーライドでイベントドリブン

EventTargetクラスのコンストラクタで



constructor: ->
@_listeners = {}
# Eventクラスで定義されたイベント名と
# 同じ名前のメソッドを持っていれば呼び出すようにする
for own prop, ev of enchant.Event
@addEventListener(ev, ((ev) -> ((e) -> @[ev](e) if @[ev]?))(ev))


enchant.Eventクラスの持つイベント名に対して、それぞれイベントリスナを追加しています。


イベントを受信した際に、クラスがそのイベント名と同じ名前のメソッドを持っていれば、それを実行するようになっています。


現状




  • サンプルのゲームが動く

  • メソッドをオーバーライドする形でのイベントドリブンプログラミングが出来る

  • CoffeeScriptのデバッガがないのでデバッグしづらい

  • GitHubにてオープンソースで公開


これから


バグがあれば直しますので@までご報告ください。


なるべくenchant.jsの機能追加等に追従出来るようにしようと考えています。


後は9leapのプラグイン等をCoffeeScriptで書直します。


enchant.coffee自体も整理したいのですが、まずは9leapで実際に使えるようになることを目指します。


質問等


何か質問等ございましたらTwitterで@宛にmentionをください。


もしくは以下のアドレスまで連絡をください。


http://services.nexodyne.com/email/icon/5JhEZ.J3qJ4%3D/LFg9q1s%3D/R01haWw%3D/0/image.png


よろしくお願いします。





2011年11月19日土曜日

日本Androidの会 沖縄支部 workshop@Naha Vol.13で発表してきた



日本Androidの会 沖縄支部 workshop@Naha Vol.13 : ATNDで発表しました。


今回はUstreamで勉強会の様子が配信されています。


USTREAM: ITカレッジ沖縄: 専門学校 ITカレッジ沖縄がお送りする番組!イベント等の様子を配信!.


Twitterのハッシュタグは#ojagnaha1119


追記


振り返りコメント


Google グループ


Togetter


OJAG workshop@Naha Vol.13 - Togetter


今日のメモ




  • 金子さんのDotcloudの話


    • 実際にコマンドを打ってdotcloudを使ってみる。

    • JSONICを使ってRESTfulなサービス、AndroidからJSONICを叩く



  • 僕の発表


    • 発表終わってから教職員から「えっと」が多い。喋るのが早いとの突っ込みが。

    • 見てくださってダメだしまで貰えてありがたいです。次回直す。



  • 告知・LT・KPT




鈴木さんのボードを見た。なんか面白そうだったのでにやにやが止まらない。


電子工作がやりたくて自分もArduino買ったので何かネタでも作ろうかな。


僕の発表内容


ミク☆キュンの紹介をしてきました。


Ustream

僕のセッションもUstreamで配信されております。



当日の発表資料


内容的には前に書いたエントリと被ってる所が多いです。




反省点


プレゼンについて

Ust見直してプレゼンの反省




  • 「~なんですけど」「で、~」「で、えっと」「えっと」が多い。


    • 自分で数えてみたけど50回弱「えっと」と言ってます。



  • 緊張のあまり早く喋り過ぎて噛む。

  • 「ちょっと」「多分」「なんか」は自信なさげに聞こえる。

  • 「ミク☆キュン」という名前を使って紹介してないような。wwww

  • 「9日間」を「ここのかかん」と読まず「くにちかん」。

  • 「9leapにアップロードして」を「9ロードにアップロード」といったり緊張してるなー。

  • 20分枠で13分程度で発表終わる。2分質問で15分程度。


話の途中に「えっと」が挟まると「かくっ」と引っかかる感じがするよね。


それが無ければもうちょっと良い感じに聞こえるかも。


多分「考え中」に微妙に空いた時間を埋めるために「えっと」を挟んでるのかと。


プレゼンの内容をもっと自分で把握しておけば解消されると思う。


発表は20分の予定が15分で終わったけど、開始時間が5分遅れたので結果的にうまく収まりまったかと。


発表内容について

KPTでもっとソースコード等について知りたい、という声もあった。


今回は具体的な中身については触れないつもりで20分貰ったので、省いた。


次回発表するときはもう少し具体的な内容入れた方がいいのかも。


あるいはもっと非技術的な発表に走るとか。


感想


はじめての発表で緊張したけど発表できて幸せだー!


学校入ってから勉強会に出始めてずっと聞き専だったので自分で発表出来るというのは嬉しい。


ネタつくってまた発表します。


追記


feedbackを更に貰ったので追記。




  • プレゼンの要素、コンテンツとデリバリ


    • デリバリは慣れ

    • 4日間でゲームを作るというコンテンツはよかった



  • 30秒以内になぜこのプレゼンするのか、話を聞く人が聞きたくなるような理由を話す。


    • この話を聞く理由がないと「なんで話聞いているんだろう?」となってしまう

    • 人間は色んな事を忘れてしまう

    • たった1つ伝えるなら何を伝えるか1つ決めて、それについて話せば覚えていてもらえる可能性が高い



  • デモの前にURLを入れるのはまずい


    • デモやる前にURL見せると皆自分の画面を見る

    • 集中力が分散してしまう




非技術系の発表ならプレゼンテーションZen + KeyNote


技術系ならKeyNoteよりもorgモードのHTML5 Presentationと



Presenting Research in Science and Engineering

Presenting Research in Science and Engineering







この本がお勧めだと教えて頂いた。





2011年11月10日木曜日

Android+MacRubyでMacを操作するアプリを作ったよ



AndroidアプリからMacを操作するPaddapというアプリを作りました。


hanachin/paddap ? GitHub


どんなアプリ?


一言で説明すると、AndroidをMacのトラックパッド代わり等に使うアプリです。MacRuby使ってます。


週末ものづくり講座の成果物です。


デモ






2011年11月5日土曜日

Okinawa.rbの勉強会に参加してきたよ!



勉強会はブログ書くまでが勉強会!


Okinawa.rbの勉強会に参加してきました。



具体的には、iPhone勉強会のやり方に倣って、Ruby/Rails初心者な方達には過去の勉強会資料などを使ってチュートリアルを行い、そうでない方々にはモクモクとハッカソンをしてもらう、という形です。

僕はモクモクとハッカソンしました。


ハッカソンの様子。真ん中で寝てるのが僕。


http://29.media.tumblr.com/tumblr_lu74q7cR8m1qzr282o1_500.jpg


Instagram


僕がハッカソンで書き直したかったもの


「はてなブックマークのタグ付けのデータを元に自分(や他人)が今興味をもっていることを視覚化したい。」


そう思ってしこしこ授業中に作ったのがこちら。


f:id:h6n:20111106014949p:image


Processingを直接使うより手慣れた言語でやった方が早く出来るだろう。


データの取得も表示も同じ言語でやった方がやりやすそうだ。


ということでプロトタイプをRubyで書きました。




  1. 自分のはてなブックマークのAtomフィードをダウンロード

  2. Ruby + Nokogiriでタグ等を抜き出す

  3. Ruby Processingを使って表示


という流れ。これを皆が見れるようにウェブブラウザで動くように書き直そう!というのが僕の今日のハッカソンの目標。


ハッカソンでやったこと


とりあえずブラウザでProcessing.js使って加工済みのデータを表示するところまで出来ました。


f:id:h6n:20111106022523p:image




  1. はてなブックマークのデータを取りたいのでAPI調べる


    1. どうやらja/bookmark/misc/feed - Hatena Developer Centerを参考にフィードのURLにパラメータ渡せば欲しいデータとれそう



  2. Anemoneっていうクロール用のgemがあるっぽいので入れて少し使ってみる

  3. Sinatra等でサーバー側書いたり、Anemoneでデータ取って来るにしても表示出来ないとどうしようもない

  4. とりあえずRuby Processingで書いたやつをProcessing.jsに移植


    1. Rubyでクラスとか使ってたのをJSで直接書くのはやだ

    2. CoffeeScript使おう

    3. Processing.jsのサンプルをCoffeeScriptで書いて動くのを確認

    4. 気がついたら昼。飯食べに行きつつ書き直し。

    5. [ ].push 123はアリなのに[ ].shiftは駄目で[ ].shift()と書かなきゃ駄目など、引数無しの関数あたりでハマる



  5. 同級生がやってたTry Rubyにちょっかい出す

  6. 気がついたら17時すぎててタイムアウト…


といった感じでした。


書き直す前の元データと書き直した奴まとめて成果物として置いておきます。


全部まとめてzip


反省点



  • ハッカソンは昼飯かって持ってきてたほうが時間節約出来る

  • 自分に優先順位と時間制限をつける

  • 下調べが足りてなかった orz


    • Processing.js周り

    • CoffeeScriptもチュートリアル一通りやってて満足して触ってなかったし

    • よく考えるとフィード取ってきて云々もRubyじゃなくてクライアント側のJSで出来るだろう


      • 最初のアイディア話して意見聞いてもよかったのでは



    • 今日はCoffeeScriptしか書いてないけどRubyで書いたのを移植、だからRuby勉強会のハッカソンの内容的にはいいはず…!


      • ほんとはSinatraとか使ってそこでRuby分補給する予定でした orz





  • 勉強会終わるまでにデプロイが理想

  • もっと話しかければよかったー&今度は懇親会出よっと


    • 懇親会ではなちんさんは何者かという話があったらしいww

    • 「誰一人として本名も年齢も経歴も知らない」中yasulabさん経由で経歴がばれるという謎の現象



  • 初めてバスで帰った。800円ちょいで那覇市内までいける。


    • Googleさんによると自宅まで徒歩2時間半ぐらい。Googleさんを信じて次は歩いてみようと思う。




感想


こういうもくもくもいいですね。楽しかったー。自分も(完全ではないにしろ)ブラウザで動くようになったし。


同級生がRubyハマってくれたようだし、初めてRubyやる人多かったけど皆楽しいって言ってましたね。(英語がつらいとも…)


Okinawa.rbの人に長田のうどん屋、栄町のサワディ・おでんの東大など美味しそうな店紹介してもらった。行かねば。(特にうどん)


今月は26・27日にもハッカソンがあるのでたのしみです。2日も実装に使えるのでいいネタ考えねば! (2つ作るのもありなのかな)


リンク


当日資料


世界の麦汁さん

Okinawa.rbの勉強会に初参戦してきたよ: 麦汁三昧


libkinjoさん

忘れ物しないようにチェックを入れる事が出来るウェブアプリ





DontForgetSomething


ソースコード


yamanetoshiさん

Node.jsいじってたらしい。自分もいじりたい。


ハッカソン - /var/log/messages


ふりかえりメモ

Google Groups


Togetter

第3回 Okinawa.rb 勉強会 - ハッカソン/チュートリアル - Togetter





2011年10月26日水曜日

enchant PROを使ってゲーム開発してハマったとこ4つとこれからいじりたいとこ



enchant PROを使ったゲーム一番のりです


3Dスロット風ゲームです。


9leapアプリから「ぼか☆すろ」を開いて遊ぶ事が出来ます。


9leap : ぼか☆すろ by hanachin_ - どこでも遊べる、投稿型ゲームサイト


http://dl.dropbox.com/u/3622136/9leap/play.png


このエントリでは開発環境と、アプリ開発中にハマったところ4つと、これからいじりたいとこを書きます。


開発環境について


ソース書くのはMacBook Airで作業しました。


enchant PROを使用した作品の動作確認にはAndroidの実機が必要だと考え、開発用の実機としてICONIA TAB A500を学校から借りました。


しかしICONIA TABではOrientationセンサーと3Dしか動作が確認出来ませんでした。


またCameraはlogcatのログを読む限りでは初期化されてるようですがプレビュー表示が出来ませんでした orz


なので今回は3Dだけを使ったゲームを作ることに決めました。


ハマったところや問題点


※僕の環境(とその時試した状態)ではうまく動かなかったけど、他の人のところでは問題なく動くかもしれません


ゲームのソースは9leap : ぼか☆すろ by hanachin_ - どこでも遊べる、投稿型ゲームサイトから入手出来ます。


1. プラグインの読み込み


enchant('nineleap');


enchant.js初心者なので明示的にプラグインの名前を指定する方法を知らず、プラグインが読み込まれないことがありハマりました。


2. 縦長の画面におけるGameのtouchイベントの発生するエリアとScene3Dの描画エリアの違い


game = new Game(320, 320);


という風にGameクラスのインスタンスを作成しています。


Scene3Dは縦長の画面全体を使って描画されてるっぽいです。


画面全体のうちどこかを触ったときに何かしたいとき



game.rootScene.addEventListener('touchstart', function (e) {
// ...
});


このようにSceneのtouchstartイベントに書くと赤線で囲った範囲しか反応しません。


http://dl.dropbox.com/u/3622136/9leap/touch_area.png


Gameクラスを320x320で初期化しているからだと思います。


ちなみに未解決です。いい方法あったら教えてください。


3. Labelで描画したテキストの残像が消えない


var label = new Label('foobar'); // 1
game.rootScene.addChild(label);
label.text = 'hoge'; // 2
label.text = 'fuga'; // 3


のようなコードで、1で初期化したテキストの描画が2でテキストを再設定した後も消えず、3で再設定すると2は消えるが1は残ったまま、というような事がありました。


9leapにあがっているARサンプルでも同じ現象を確認しました。


なので、それを解消するためにこのようなコードを書きました。



var bg = new Sprite(100, 20);
bg.backgroundColor = '#fff';
game.rootScene.addChild(bg);

var score = 100;
var scoreLabel = new Label('score: ' + score);
var updateScore = function () {
bg.x = 0;

scoreLabel.text = 'score: ' + score;
}
scoreLabel.addEventListener('enterframe', updateScore);
game.rootScene.addChild(scoreLabel);


スコアを毎フレーム再表示する処理です。


スコアを表示するLabelの後ろに背景Spriteを設置しています。


scoreLabel.textを再設定する前にそのSpriteのxを移動させて背景を再描画し、labelのtextの残像を消しています。


4. 箱が明るくならない

箱を明るく表示させたいのに3Dのボックスの明るさのいじり方が分からず暗いままでした。


http://dl.dropbox.com/u/3622136/9leap/play_old.png


結論からいうと箱を自己発光させました。


surface.emission、Surface3Dのemissionというプロパティに値を渡すことで発光させる事が出来ました。



surface.emission = [0.8, 0.8, 0.8, 1.0];


箱を明るく表示させるためには光源の位置を移動させるなどの方法があると思いますがドキュメントにそれらしい事が書いてありませんでした。


このemissionというプロパティもenchant PROのドキュメントには書かれていませんでした。


enchant PROのソースを読むとSurface3Dでまだドキュメントが用意されてないプロパティとして




  • ambient

  • diffuse

  • specular

  • emission

  • shininess


などがありました。


EP_GLという変数を通してAndroid側のOpenGLのオブジェクトをいじっているようです。


なので




  1. emissionなどのプロパティに渡す値はOpenGLの同等の関数に渡す値を渡せばよい

  2. JSで渡すならどうするだろう?


と考え、配列を渡すことで上手く発光させる事が出来ました。


これからenchant PROをいじるなら


EP_はおそらくenchant PROの頭文字を取った接頭辞で、他にもEP_がついてる変数が




  • EP_SENSOR

  • EP_CAMERA

  • EP_ZXING

  • EP_AR

  • EP_MEDIA

  • EP_SOUND


など、いくつかあります。


これらのオブジェクトの持つプロパティについてどうなってるのか、気になります。


for in文を使ってこれらの持つオブジェクトのプロパティやメソッドを調べたいですね。


まとめ


4つほどつまずく事もありましたがAndroidネイティブの機能を手軽に呼び出すことが出来ました。


今後使う人が増えたりドキュメントが充実したり情報が増えるといいなー!





2011年10月24日月曜日

enchant.jsでゲームを作ってる中、考えたことつまずいたこと、これから(OJAG Naha Hackathonその後の話)



OJAGの勉強会でenchant.jsのハッカソンに参加しました。


OJAG workshop@Naha Vol.12に参加してゲーム作ってきた! - はなちん C-x C-c


その後9leap×ピアプロ 初音ミクチャレンジに応募するべく作品を制作しました。


出来上がった作品は2作品です。どちらもソースコードは公開しています。


1つめ


4日間程度かかりました。画像とBGMを友達に頼んで制作。長い時間遊べるテトリス的なものを目指しました。


9leap : ミク☆キュン! by hanachin_ - どこでも遊べる、投稿型ゲームサイト


制作中工夫した点



  • 自分では作れない画像を友人に制作依頼

  • BGMも依頼

  • プログラムで使いやすいように画像を作ってもらう

  • ソースコードを編集したら誰かにすぐ見てもらえる環境作り

  • ゲームのパラメータをソースコード書き換えずいじれるようにする


遭遇した問題点



  • Firefoxで音がならない事件


などなど。細かい事は後から書く or 発表します。


2つめ


3Dスロットゲーム。enchant PROを使用


9leap : ぼか☆すろ by hanachin_ - どこでも遊べる、投稿型ゲームサイト


工夫した点



  • enchant PROが出た翌日からコンテストに間に合わせるために制作開始

  • 明るさを設定する方法がドキュメントに書かれてない


    • とりあえずproのソースを読んだ



  • 前はscriptのsrcに指定するだけでutilプラグインやnineleapプラグインが使えるようになった気がするのですが、出来なくなってた


    • enchant('util', 'nineleap');で解決



  • まず、動作確認が出来る実機を使って、動くセンサーがあるか、あるならその値を取得出来るか試した


    • ARを使いたかったがICONIA TAB A500で上手くうごかなかった

    • カメラも動かなかったので諦めて別の方向で試す




などですかね


全体として意識していたところ


週末ものづくり講座


この授業を受けています。かなり刺激を受けております。(授業でAndroidアプリも1つ作成したのですがそれはまた別のエントリにて)


enchant.jsの作品もその授業の一環として制作し授業内でも進捗の報告やデモ等しました。


そこから引用すると



具体的なプロセス:
- 1. 良いアイデアを見つけたら、3日以内にそのプロトタイプを作成し、評価する。
- 2. 評価の結果が良ければ開発を続ける。悪ければ、また新しくプロトタイプを作成する。
- 3. 良いモノが出来あがればマーケットに投稿。そうでなければOSSとして公開する。

といった感じです。授業もこの流れ。


この流れを実践出来るように頑張ってみました。


ミク☆キュンはとりあえず作って何人かに見せて、感想を貰い改良し(取り入れない/実装出来なかったものもありますが)、最終的に9leapでソースコードと共に公開しました。


評価はまだ途中かな? プレイ数ものびるかと思いきやそこまで伸びませんでしたね。


理由はいくつかあると思いますが



失敗から得られた知見を大切にする。

と書いてあるのでここに残しておきます。


疑問や思い浮かんだ解決策など



  • 同時期に同じジャンルでもっと本格的なゲームが投稿された


    • 被らないジャンルを狙う戦略を取った方が良い?



  • 複雑すぎた


    • キャラクターを3人に増やしたりルールが複雑になった。


      • シンプルな方がうける?



    • 1プレイに39秒の制限をつけ制限時間を延ばす仕組みを作ったがそれだとプレイ数がのびない


      • むしろ制限時間をへらす方法を考えるべき?

      • プレイ時間が短い方が何回もプレイ出来る?

      • 何回もやりたくなる変化とか仕掛けが必要なのかも、今だと玉うつだけでスコアぐらいしか変動する余地がない



    • サウンドやフォントも3人分用意したのでスマートフォンでの動作が重くなった


      • 画像よりも音声、特にBGMが圧倒的に重かった。

      • キャッシュするようなプラグインを使うべき?





  • enchant PRO出たばかりのものでドキュメントが少なかった


    • ソースコード読む力をもっとつける? いじったAPIが少ないけど3Dプログラミングの知識があればもっといけた?



  • enchant PRO試せる実機がなかった


    • 友達のものを借りる手もあったのでは?

    • 2.3以上じゃないと試せないしばりが今後も出てきそうだしAndroid2.2の端末のままでいいのかな?

    • もしもこれがiPhoneから出ていて、僕がiPhoneを持っていたら、実機はほぼ1種類に縛れるから試せたのかも?



  • どのぐらいまで出来てるものを試せばいいのかな?

  • 時間をかけずに大量のゲームを作るにはどううれば?


    • やっぱり作り置き、というかコピペや参照出来るソースが必要?

    • ネタ作りに時間が結構かかるのでネタ本があるといい?

    • パクったほうがいい?



  • ゲームを更新すると最近投稿されたゲームに表示される


    • おそらくトップに表示されないとプレイされる回数は非常に少なくなる。

    • 常にトップに表示されるために自動更新の仕組みがあると便利?



  • 宣伝用にYoutubeとニコニコ動画にも動画をあげた


    • だが再生されなかった。そもそも再生されるためにもある程度の宣伝が必要っぽい。

    • 再生してもらえるようなBGMだったりカテゴリを選ぶべきだったのかな?



  • enchant PROのデバッグが実機でしか出来ない


    • 実機でデバッグするために毎回、フォルダをzipで固めてウェブにあげる必要がある


      • 自動化できないか?





  • ゲーム作りが初めてだった

  • 初音ミクでなければならないゲームではなかった


    • もっとキャラを生かすべきだったのか?




ざっとでてくるのはこんな感じでしょう。


まだ審査期間があるので結果は分からないけれど、途中で何度も細かいところで引っかかった。


都度解決したが一部解決出来ていない点や疑問も残った。


次回はこれを直すようにしたら今より少しだけましになるのではないだろうか。


enchant.jsを使って9leapに投稿してみて


enchant.jsを使うとほんとに簡単にゲームが作れた。enchant PROを使うと3Dがめっちゃお手軽に扱えた。


短期間で集中して何か作るのは楽しい。9日間のチャレンジ、9日間でゲームを作る!という企画は本当に素晴らしいと思う。


工夫したり苦労した点は次回につなげて行きたい。


今後


4Gamer.net ― プログラミングは最高だ。無差別級ゲームコンテストも発表されたUEI「enchant.js meetup!」レポート


によればopen leapという学生以外でも参加出来る無差別チャレンジがあるっぽいので是非応募したい。


こんな素敵な場所を提供している9leap : トップページ - どこでも遊べる、投稿型ゲームサイトさんはすごくいいサイトなので皆さん是非参加してみて!


まぁenchant.js以外にも面白そうなことがあったら積極的にものつくろうと思います!


ものつくりと発表はセットらしいので、今後は発表など出来たらいいな!





2011年10月16日日曜日

OJAG workshop@Naha Vol.12に参加してゲーム作ってきた!



昨日は日本Androidの会 沖縄支部の勉強会に参加しました。


成果物は9leap : OJAG Naha Hackathon by hanachin_ - どこでも遊べる、投稿型ゲームサイト


今回の勉強会は




  • 9leapの伏見様(@)のお話


    • 今回のために来沖(日帰り)してくださったみたいです。超ありがたいです。

    • enchantと9leapの紹介

    • ライブコーディング



  • enchant.jsを使ったハッカソン!


    • ハックとマラソンを掛け合わせた言葉で皆で集まって開発する感じのイベント

    • 今回は2時間半ちょい黙々とゲーム作成。



  • 懇親会


    • 10時間で21本ゲーム作成の話などなど



  • 懇親会2


    • 居酒屋でMacBookを4台並べながらのアイデアソン




という感じでした。


僕も2時間半ぐらい黙々といじってTouchTheNumbers風のゲームを作成しました。懇親会も楽しかったです。


以下、当日聞いた内容の自分なりのまとめと、ハッカソンで作ったもの、作ってた時の過程を書きます。


9leapについて


9leapという若いプログラマ向けのゲームコンテストサイトがあります。(enchant.jsで作られたゲームが数多く投稿されています)


その9leapのプロジェクトリーダーの伏見様が1時間ほどenchant.jsの紹介とライブコーディングをしてくださいました!(テキストエディタはCotEditorでした)


スライドはまだあがってないようですが内容的には「enchant.js & PRO」第21回 html5とか勉強会 ショートセッションのような感じでした。


enchant.jsについて


enchant.jsはJSでBASICみたいにゲームを短く楽しく書けてしかも軽い、モダンなブラウザがあればどこでもゲームが動く!というすごいものです。


確かに書いてみるとめっちゃ楽でした。1枚の画像にまとめられてる複数の絵を切り出すのがプロパティ指定するだけで出来たり。


ゲームがっつり書いたことない自分でも2時間半で1つゲームが作れました!


こんなに簡単に作れるなんて中身がどうなってるのか気になるので是非enchant.jsソース読みしたい。


あと、ゲームつくり楽しかったのでリトライしてみたくなりました。っていうかリトライしますw


enchant PRO

スマートフォンのカメラ等をenchant.jsから簡単に扱えるらしい。ARも簡単に書けるようでめっちゃ気になる…


ハッカソンで作ったもの


TouchTheNumbers(5x5のますにランダムに配置された1から25までの数字を順番よく押して時間を競うゲーム)を作りました。


先輩のiPod touchでプレイしてハマってしまったのが理由。


動きのあるサンプル見せてもらったのに動きが地味なのもの作ってしまったので後でもっと楽しい感じに書き直そうかと orz


9leapで公開したので以下のリンクからプレイ出来ます!


9leap : OJAG Naha Hackathon by hanachin_ - どこでも遊べる、投稿型ゲームサイト


作ってた時の過程


画像の出し方、移動程度は予習してました。


目標は「必ず完成させて公開する」でした。


私が今受講している週末ものづくり講座の影響です。


ステップ

ステップとしては




  1. 数値を画像に変換


    1. まずは0から9までの変換

    2. それを利用してn桁対応



  2. 数値の入ったますを作る


    1. まずは普通のますを作る

    2. 数値を画像に変換してそのますにのっける



  3. 1から25までの数値の入ったますをランダムに配置

  4. 1から順に押されているかのチェック

  5. 時間の計測

  6. 9leap公開・スコア送信


という感じで進めていきました。


数値の入ったますを作る処理が出来るまででハッカソンの時間の2/3、順に押されてるかのチェックと時間の計測を実装したとこで2時間経過、その後9leap公開、送信ちょっとした修正で30分ぐらいかかりました。


ソース

ソースコードは以下のような感じ。


9leap : OJAG Naha Hackathon by hanachin_ - どこでも遊べる、投稿型ゲームサイトからzipで一式落とせます。



Array.prototype.shuffle = function() {
var i = this.length;
while(i){
var j = Math.floor(Math.random()*i);
var t = this[--i];
this[i] = this[j];
this[j] = t;
}
return this;
}

enchant();

count = 0;

window.onload = function() {
var game = new Game(320, 320);
game.fps = 15;
game.preload('font.png');
game.onload = function() {
function makeBlock(w, h) {
var block = new Sprite(w, h);
block.x = 0;
block.y = 0;
return block;
}
function squareBlock(size) {
var bg = makeBlock(size, size);
return bg;
}
function addBorder(block, size, color) {
var wrap = new Group();
var bg = makeBlock(block.width + size * 2, block.height + size * 2);
bg.x = 0;
bg.y = 0;
bg.backgroundColor = color;
block.x += size;
block.y += size;
wrap.addChild(bg);
wrap.addChild(block);
return wrap
}
function numBlock(n) {
var block = new Group();
block.x = 0;
block.y = 0;
block.width = 44;
block.height = 44;
// 64
var bg = squareBlock(44);
bg.backgroundColor = "#fff";
var bg = addBorder(bg, 2, "#2f4f4f");
block.addChild(bg);

var nums = (""+n).split('').map(function (x) { return parseInt(x); });
for (var i = 0; i < nums.length; i++) {
var sp = numSprite(nums[i]);
sp.x = i * 16 + 8;
sp.y = 16;
block.addChild(sp);
}
return block;
}
function numSprite(n) {
var sp = new Sprite(16, 16);
sp.image = game.assets['font.png'];
sp.x = 0;
sp.y = 0;
sp.frame = n + 16;
return sp;
}

function init() {
// var scene = new Scene();
var scene = game.currentScene;

var nums = [];
for (var i = 1; i <= 25; i++) { nums.push(i); }
nums.shuffle();

for (var i = 0; i < 5; i++) {
for (var j = 0; j < 5; j++) {
var index = (i * 5) + j;
var block = numBlock(nums[index]);
block.x = j * 48;
block.y = i * 48;

var click = (function () {
var n = nums[index];
var b = block;
return function (e) {
var x = e.x;
var y = e.y;
if (b.x < x && x < b.x + 48
&& b.y < y && y < b.y + 48
&& count == n) {
count++;
b.backgroundColor = "black";
var paint = squareBlock(48);
paint.x = b.x;
paint.y = b.y;
paint.backgroundColor = "#fff";
scene.addChild(paint);

if (count == 26) {
var score = Math.floor((start / game.fps) * 10)/10;
game.end(10000 - score, "Your score is " + score);
}
}
}
});
block.addEventListener("touchstart", click());

scene.addChild(block);
}
}

count = 1;

//game.replaceScene(scene);
}

init();

start = 0;

game.rootScene.addEventListener('enterframe', function () {
start++;
});
};
game.start();
};


感想


ハッカソン楽しい。動いたもの公開して人が遊んでくれるとやっぱり嬉しい。


ゲームプログラミングやるとプログラミングが出来るよになるというのも話されていたのでゲームを作りたい。


そして作ったゲームを9leapにドシドシ投稿していきたいです。


刺激を受けた部分としては懇親会でお話されていた10時間で21本というのを聞いて自分も手をもっと早く動かせるようになりたいなぁ、と。


# enchant PROのARやTwitterでやりとりされていたnode.jsでエアホッケーとかすごく楽しそう





2011年10月6日木曜日

ハッカソンの前にenchant.js環境構築



日本Androidの会 沖縄支部 workshop@Naha Vol.12 : ATND


来る10月15日にOJAGの勉強会があります。当日予定されているハッカソンに向けて開発環境を整えます。


ハッカソンで使用するのは以下なライブラリ(appMobiも使うのですが別エントリでまとめます)


no title


HTML5とJavaScriptで簡単にゲームが書けるゲームエンジン、様々なプラットフォームに対応しています。


環境構築


GitHub ? Social Coding


このページのDOWNLOAD PACKAGESのバージョンが一番新しい奴をダウンロードして展開します。


これで環境構築は完了です。(多分)


使いか方は多分、HTMLファイルの中のscriptタグでenchant.jsを読み込むだけ。


あとはゲームの処理を別のJavaScriptファイルに書いてそれを同じようにscriptタグで読み込ませます。


HTMLとJavaScriptを何で書くかはお好みですがうちの学生としてはvimを使え、となるのかな?


私はIDE使った方が楽だと思います。エラー表示とか出るし。EclipseかAptanaお勧めです。


ついでに9leapも登録する

9leap : トップページ - どこでも遊べる、投稿型ゲームサイト


enchant.jsを使って作られたゲームがたくさん投稿されてるので参考になるはず。


登録しなくてもソースは読めますが自分もコンテストに参加してみたいので登録しておきます。


Twitterのアカウントがあれば簡単に登録出来ます。




  1. 右上のログインを押す

  2. Twitterのアカウントでログインを済まし連携アプリを認証を押す


おそらくこれだけで完了です。あれ?自分前に登録したっけ? @taka16_O あたりに確認取ってもらおう。


ドキュメント


enchant


開発者の方によるスライドが分かりやすいです。


とりあえずこれを参考にざっくり概要を理解。


GitHub Pages ? File Not Found ? GitHub


実際書くときはリファレンスとしてここを参照するかと。


次のステップ


ひとまずenchant.jsをダウンロードして展開すれば環境構築は完了です。


日本Androidの会 沖縄支部 workshop@Naha Vol.12 : ATND


no title


などに掲載されているチュートリアルやサンプルをなぞって書いていく事になるかと。


来週の放課後当たりに時間が取れればいいなぁ。


# クリエイター科な学生の方は画像素材等も自分で作れそうですね、相談してみよう…





2011年10月4日火曜日

7つの言語7つの世界 Io 3日目



ついにIoも3日目、雑ですがメモと感想を。

DSLを作る話。


phonebook.io

わざわざ文字列をパースしなくても、電話帳のリストを構文として解釈するようにIoを変更({}や:の意味をかえる)

phonebook.ioがそれ。ところでp64のforEachはforeachの間違いかな?なんかここだけ違う。Rubyっぽい。

演算子が自由に定義可能なのは2日目で見たけど{}までも変更出来るなんてヤバい。curlyBracketsメソッドを定義することで{}の動作をいじれる。





Ioのmethod_missing

forwardメッセージをいじればいい。

forwardではメッセージが存在してない場合親に転送する事をしているらしい。

なのでこれを上書きしちゃうとIoとは別ものに…

ここらへんから頭がこんがらがる。

Builder := Object clone
Builder forward := method(
writeln("<", call message name, ">")
call message arguments foreach(
arg,
content := self doMessage(arg)
if (content type == "Sequence", writeln(content)))
writeln("</", call message name, ">"))

Builder ul(
li("Io"),
li("Lua"),
li("JavaScript"))


平行性


Ioには3つ平行性ライブラリがある。



  • コルーチン

  • アクター

  • フューチャ

コルーチン

処理を自由に停止・再開出来る。

@や@@をつけて非同期にメッセージを送信する。@はフューチャを返す。@@は自分のスレッドでメッセージを開始出来る。

yieldを呼ぶと別の処理に制御をうつす。yield書かなくても適当に自動でyieldしてくれるらしい。

制御を移すタイミングをyield呼ぶことで自分で指示出来るのがポイントっぽい。

自分で制御を渡すことが出来るので協調動作も書きやすい。

JavaやCベースの言語はプリエンティブマルチタスキングと言われる平行性の概念を用いているらしい。

第12回 Haskellで学ぶ並列プログラミング(その3)並行プログラミングと並列処理 - 本物のプログラマはHas...:ITpro

実行している処理に割り込む形でタスクを切り替えるので,このような形のマルチタスクを「割り込み型(preemptive,プリエンプティブ)マルチタスク」と呼びます。これに対して,スケジューラではなく実行する処理の側で明示的にタスクを切り替える形のマルチタスクを,「非割り込み型(non-preemptive,ノンプリエンプティブ)マルチタスク」あるいは「協調的(co-operative)マルチタスク」と呼びます。

プリエンティブマルチタスキングな平行方式と変更可能な状態を持つオブジェクトを組み合わせると、予測出来ずテスト方法もアレでデバッグが難しくなる云々。

確かに勝手に割り込んで色々変え合ってたら大変だよね。

「アクターのような高レベルの抽象化を実現する基本的な構築ブロック」がコルーチンらしい。

うーん、書いて自分で読み返してみてイミフ orz

アクター

アクターはメッセージの送受信、アクターを作る事が出来るとか。

受信したメッセージはキューに入れてコルーチンで処理していく。

なのでスレッドのように互いに制限なく変更することが出来るわけではないみたい。

キューで処理していくのでちゃんと制御されてるとか。

Ioでは@@で非同期メッセージ送ればそれがアクターになる超絶便利機能。

x @@foo; y @@bar;


すると同時に実行される。fooとbarの中でyieldを呼んで制御を移す事も出来る。Ioかっけー

フューチャ

@で非同期メッセージを送るとFutureオブジェクトが帰って来る。

非同期メッセージが完了する前にFutureオブジェクトを使うと、完了して値が帰って来るまでブロックされる。

時間かかる処理を@で呼び出しといてFutureの値使わない処理ごにょごにょしてから、Futureの値を使う処理をかく(とFutureの値が帰って来るまで待つ)感じなのかな。

Ioにはデッドロックを自動的に検出する機能もあるらしい。

試してみよう


XMLのやつ



  • 本文のLispMLを改良してインデントさせる

  • 本文のLispMLを改良して属性を処理出来るように。第1引数がMapだったら属性を追加



なんかXMLのやつ想像以上に時間かかった。

args first codeをdoStringしてるんだけど、doMessageでも出来んのかな?

自分の場合上手くいかなくてなんか結構汚い感じ。

これは他の人の回答めっちゃ参考にしないといかんなー

角括弧のリスト構文



  • 角括弧を使ったリスト構文を作成



LispMLに苦労したけどこっちは5分ぐらいで出来たw

これだけで[]でリストが作れるようになる。すげー!

添字アクセスまで作る気力は私に無かった。

ちょっと疑問点




  • 最後の連続したとじ括弧は1行にまとめちゃってもいいのかな?

  • インデントどうつけよう

感想


平行性の話がまだきちんと理解出来てない感じ。

でもIoだと、ただ単にメッセージに@@とか@つけりゃ平行動作・協調動作させたり処理待ちも勝手にやってくれてかなり便利そう。

Io奥が深い…




2011年10月2日日曜日

7つの言語7つの世界 Io 2日目



no title


この資料が分かりやすかった。


以下メモ書き




  • 言語の基本的な動作を覗く

  • ループ


    • loop(処理)

    • while(条件, 処理)

    • for(カウンタ名, 初期値, 終了値(含む), senderを伴うメッセージ)

    • for(カウンタ名, 初期値, 終了値(含む), 増分, senderを伴うメッセージ)



  • 条件分岐


    • ifは関数

    • if(条件, 真の場合, 偽の場合)

    • if(条件) then(真の場合) else(偽の場合)

    • if(条件1) then(条件1が真の場合) elseif(条件2) then(条件2が真の場合) else(偽の場合)

    • if(条件, 真の場合, 偽の場合)は真偽のコードどちらかを評価した結果を返す



  • 演算子


    • OperatorTableで演算子表を確認出来る


      • 優先順位が分かる

      • 演算子の追加はaddOperator(演算子, 優先順位)



    • 1 + 2は1 +(2)というメッセージにコンパイルされる。1に対して+(2)というメッセージ送る

    • addOperatorでOperatorTableに演算子を追加しないとエラーが出る例





$ io
Io 20110905
Io> List ++ := method(a, a foreach(v, call target append(v)))
==> method(a,
a foreach(v, call target append(v))
)
Io> list(1, 2) ++(list(3, 4))
==> list(1, 2, 3, 4)
Io> list(1, 2) ++ list(3, 4)

Exception: nil does not respond to 'foreach'
---------
nil foreach Command Line 1
List ++ Command Line 1

Io> OperatorTable addOperator("++", 4)
==> OperatorTable_0x7fc798c73040:
(略)
Io> list(1, 2) ++ list(3, 4)
==> list(1, 2, 3, 4)




  • メッセージ


    • メソッド呼び出すとcallスロットにcallオブジェクトが設定される

    • callオブジェクトのスロットはsender(送信元), target(宛先), arguments(引数)

    • メッセージの引数はmethod(arg, arg)の様にargを書くと評価される

    • メッセージの引数を書かないと評価されない


      • method(call message argAt(0)) <- argAt(0)で0番目の引数を取る事が出来るが評価はされない



    • えばるならevalArgAt

    • ほんとに,以外はほぼメッセージ… 純粋! かっこいい!

    • unlessの例


      • call sender doMessage(call message argAt(2))

      • 送信元の環境で2番目の引数を評価

      • 短くやる方法がevalAtArg



    • animalsの例


      • プロトタイプを辿りながらスロットを出力していく

      • selfはcallのtargetに設定されてるのかな

      • 1つのオブジェクトが複数のプロトタイプを持つ場合もあるらしい


        • どういうことだろうww





    • メッセージリフレクションとオブジェクトリフレクション


      • クラスの存在なし

      • call messageやselfやprotoなどメッセージやオブジェクトにアクセスする手段がいっぱい





  • asなんとかメソッドでデータ形式の変換


セルフスタディ 試してみよう


既にあるメソッドを勉強して使いこなさないとすっきり書けないですね。



本を見ながら書いたもの




感想


他の方の回答を調べたらめっちゃすっきり書かれてる。


この違いがどこからくるのか、かける時間かリファレンスをちゃんと見てるのか良い方法があるのか気になる。


今回は間があいてしまいました。1週間1言語はやはりちゃんとやらないとついていけない orz


1ヶ月の夏休み中は内定先の企業様でバイトをさせて頂きました。


プライベート時間の確保が学校居るときより出来なくなりました(週1日は元同級生と基本情報の勉強をするため空けてたり、週末も色々あったりで) orz


時間をうまく使う技術身につけないと会社入ったらあっという間に老いて死んじゃうので今のうちどうにかせねば…


今月はScheme修行の本文からもっと深く読めてない部分(Yコンビネータ等々)も読むし、PHPの勉強も始めるし、3日目はしっかり読んで、さっと練習問題まで終わらせてしまおうと思います。





2011年9月25日日曜日

Scheme修行16章



TheSeasonedSchemer (5) - /var/log/messages


自分も!をbangと呼ぶの知らなくて今まで「setびっくり!」とか「setびっくら!」って読んでました。


#!をshebangと呼ぶのと似た感じですね。


letでつけた名前は内側のlambdaからしか見えなかったりするので確かに属性みたいな感じ。


15章は1ステップずつ読まないと前の問いが後ろに影響することもあって(define した値にset!してたり)結局テスト書いてないです。


16章もそんな感じでがんがんset!してたのでテスト中途半端にしか書けてないです orz


本に書いてあるコードを1つずつ実行したログを編集して16.logとしてまとめました。


感想


途中まではメモ化にset!を使う話をしている気がしました。




  • まずは普通に再帰

  • 再帰の結果をメモ

  • (deep n)は(cons (deep (- n 1)) '())なので(deep (- n 1))がないか調べる

  • deepの再帰の中でもメモ化したdeepMを呼び出すようにする


その流れで第19の戒律



関数の二度の呼び出しにまたがり貴重なものを覚えておく際には(set! ...)を使用して貴重なものをおぼえておくべし。

が出てきました。


後半はletrecの仕組みとY!コンビネータ、YとY!の違いについて、といった感じがします。


YとY!の違いを理解するのにちょっと時間かかりました orz


この章も深い。


メモ




  • この章もset!ばかりで、テストどうかこう orz


    • 結局中途半端にテスト書きました。



  • deepやsweet-toothの実行結果をset!でlistに保存していく

  • 第19の戒律が出てきた。


    • 1回の呼び出し内で複数回使われる値はletで、複数回にまたがる場合はset!で覚えておく



  • deepM


    • findは値が見つかる場合に呼ばれる


      • 後ほどfindに値が見つからない場合を1行追加



    • findが呼び出せるかはあらかじめdeepMがmember?で調べる

    • この役割分担がいいなぁ

    • deepRを内側に取り込んで簡素化



  • p120まではメモ化の話かな?

  • p121、第17の戒律最終版、xの新しい値がx(自分自身?)を参照する関数のとき、が追加

  • 「架空の名前h1を通して自分自身の再帰的コピーを参照しているだけです」

  • Y!コンビネータ


    • 再帰的な部分だけ残してlengthに特徴的な部分を切り出す

    • Lに(lambda (arg) (h arg))を渡してる


      • hをそのまま渡すと(set! h (L h))になってしまう

      • それだと(L h)となり、hが先に評価される

      • 新しいhになる前のhの値そのものをLに渡してしまわないように、lambdaでくるんでる?





  • letrecはletとset!からなる式の省略らしい。letrecを使ったバージョンがY-bang

  • この流れが適用順手続き的Yコンビネータの導出、らしい


YとY!の違い


「Y!はこの形をした全てのfに対してYと同じ再帰関数を作り出す」


biz関数をYに適用した場合と、Y!に適用した場合とで結果が違う。


違いを確かめるために2つのことを試してみました。




  • biz関数の(lambda (a)の下に(print x)つけたら、Y!だとxがずっと1のままだった。

  • biz関数の(set!の下に(print x)つけるとYは毎回表示、Y!だと1回しか表示されない


よくよく定義を見ると




  • Yは(biz (lambda (arg) ((f f) arg)))の(f f)で自分自身を得る際に毎回bizを呼び出してる

  • Y!は(set! hする時、1回しか(biz (lambda (arg) (h arg)))を呼び出さない


(Y biz)には再帰に(set!の部分が含まれてるけど(Y! biz)では含まれてない、という違い。


Y!だとxは1のままなので終わらないです。


気になること


「ありがとう、Peter J.Landin」とあったので名前で検索したら


関連する項目でISWIM - Wikipediaを見つけ


「J演算子は継続を可能としたもので、Scheme の call/cc は J 演算子を簡略化したものである」


という興味深い記述を見つけました。J演算子…


他にもScheme手習いのYコンビネータの前半部分(lambda (f) (f f))のUコンビネータ、SKIコンビネータなど


そこらへんがっつり調べたり、いい資料あったら教えてもらいたいです。


JavaScript


JavaScriptも手続きオブジェクトがあって面白いですよね。


A re-introduction to JavaScript - MDNやってみます。


JavaScriptでクロージャを云々だとWhat’s a Closure?のレッスンも面白かったです。





2011年9月23日金曜日

7つの言語7つの世界 Io 1日目



探してみよう




確認してみよう




  • Ioは強く型付けされた言語か? 弱く型付けされた言語か?


    • Ioは強く型付けされた言語。1 + "one"はエラー



  • 0、空文字列、nilは真か偽か?


    • 0、空文字列はtrue、nilはfalse

    • (true and 0) println; (true and "") println; (true and nil) println



  • プロトタイプのスロットの確認


    • proto slotNames、protoでプロトタイプを取得してslotNamesメッセージ送る



  • =、:=、::=の違い


    • a = 1はupdateSlot("a", 1)、a := 1はsetSlot("a", 1)、 a ::= 1はnewSlot("a", 1)にコンパイルされる

    • =はスロットに値を入れる。スロットが存在していない場合例外を投げる

    • :=はスロットを作成して値を設定。

    • ::=はスロットとセッター(fooだったらsetFoo)を作成して値を設定




試してみよう




  • ファイルからIoのプログラムを実行


    • $ io -hでヘルプ見れる。普通にファイル名渡せばいいみたい。

    • $ echo '"Hello, Io!" println' > day1.io; io day1.io



  • スロットの名前を指定して格納されているコードを実行



$ io
Io 20090105
Io> a := Object clone
==> Object_0x10268e620:

Io> a fuga := method("fuga" println)
==> method(
"fuga" println
)
Io> a fuga
fuga
==> fuga
Io>


これでいいかな?他の人の見たら



Io> a getSlot("fuga") call
fuga
==> fuga
Io>


でした。


感想等


「問題は何をするか」ではない、「何をしないか」だ


フェリスはある朝突然に - Wikipedia


に出て来る台詞らしい。


かっこいい。


JavaScriptと同じようなプロトタイプベースのオブジェクト指向言語。言語自体は凄くシンプル。


プログラミング言語の仕組みを勉強するために作ったらしい。なんかすごい。


JavaScriptは人気すぎるからIoにした、って本の最初の方で書いてたけど、Ioは日本語の情報少なくてちょっと困りそう。頑張って最後まで読む。


ioに書かれてるfeatures見ると




  • small vm(1万行以下)

  • 複数のVMが同じプロセスで動く

  • ガベコレ、弱い参照

  • アクターベースの並列モデル、コルーチン

  • 64bit C99での実装

  • 組み込み言語

  • 例外


とりあえずbrewで入れました。



$ brew install io

雑記



  • Objectが一番てっぺん、Objectにcloneメッセージ送って新しいオブジェクトを作る。

  • オブジェクトはスロットを持つ。slotNamesというメッセージを送ると持ってるスロットが確認出来る。

  • 代入は=、スロットが存在しないのにFooObject = "foo"するとエラー

  • 無かったら新しく作ってくれるのが:=

  • 全てのオブジェクトはtypeに答える


    • 5 typeするとNumberが帰って来る



  • 大文字で始まる名前のオブジェクトはタイプ

  • 送られてきたメッセージに答えらなかったらプロトタイプに転送する

  • Ioではタイプも、タイプを元に作成されるオブジェクトも、どちらもオブジェクト。

  • メソッドの定義はmethod()、methodのタイプはBlock。メソッドもオブジェクト。

  • getSlotでスロットの値を取得出来る。スロットが無かったら親のスロットを辿る。

  • protoメッセージを送ると自分のプロトタイプが取れる


    • REPLも実はオブジェクトのメソッド内で実行してるのかprotoと打つと親が帰って来る



  • Lobbyに全ての名前が入ってる

  • コレクション


    • List


      • ObjectのlistメソッドでListタイプのデータが作れる

      • Listにはaverage sum at append pop prependなどのメソッドがある。



    • Map


      • Mapはハッシュのようなもの、シンタックスシュガーはない。

      • atPut at asObject asList keys sizeなどのメソッドがある





  • 真偽値


    • true false

    • どちらもシングルトンのオブジェクト、cloneを上書きして自身を返すようにする







7つの言語7つの世界 Ruby 3日目



試してみよう




感想等


3章はRubyのメタプログラミングの紹介、メタプログラミングとはプログラムを書くプログラム

Rubyの機能を使えばDSL(ドメイン固有言語)を構築することが簡単に出来る(らしい)

メタプログラミングRuby欲しくなった。

Rubyの3日分の「試してみよう」の他の人の解答見ると、奇麗なコード多すぎて嫉妬。

読んでる間ずっとリファレンスマニュアルと睨めっこだった。

もっとちゃんとした本を一冊かって頭に叩き込まれるまで勉強したいなぁ。

一番良いのは忘れないように毎日何か書く事だろうけど。書かないと何回も調べたことでも忘れちゃう気がする。

試してみようの3日目

元々定義されてるメソッドと同じheadersが設定されてたらmethod_missing呼ばれない。

なので定義されてるメソッドをundefしていく必要があるみたい。

メソッドをまっさらに消すのをブランクスレートと呼ぶらしい。

メタプログラミングに利用出来る機能



  • オープンクラス


    • クラスを定義した後からでも変更出来る

    • 普通はメソッドを追加する時に変更する

    • メソッドを追加する前に作成したオブジェクトからでも追加したメソッドを呼び出せる

    • DSLを作成する時に便利

  • method_missing


    • phpの__callとか__getのようなものか。

    • 例として出ているローマ字がすごい。

  • モジュール


    • 最も人気のあるスタイル

    • 「マクロと呼ばれるモジュールメソッドを使う」

    • acts_as_csvマクロでdefine_methodを使ってCSVファイルに関する全ての動作を定義(acts_as_csv.rb)

本見ながら書いたもの


















2011年9月22日木曜日

PHPのforeachのちょっと嫌なところ



PHPのforeachの嫌なところが1つあります。


foreach ($a as $k => $v) { ... }の$kと$vが上書きされてしまうところです。




<?php
$name = 'hanachin';
$flat = array(101 => 'Kato', 102 => 'Yoshida', 201 => 'Sato');

echo "Hello, I'm $name", PHP_EOL;
foreach ($flat as $room_no => $name) {
// $name = $flat[$room_no]みたいな処理が入ってる(?)
echo "room #$room_no: $name", PHP_EOL;
}
echo "Hello, I'm $name", PHP_EOL;

# Output:
# Hello, I'm hanachin
# room #101: Kato
# room #102: Yoshida
# room #201: Sato
# Hello, I'm Sato
# --------
?>


$nameが上書きされてしまいました。


参照と組み合わせるともっと厄介です。


foreachで使った参照をunsetしないままforeachを使うと配列の最後の要素を意図せず書き換えてしまうことがあります。



<?php
$name = 'hanachin';
$flat = array(101 => 'Kato', 102 => 'Yoshida', 201 => 'Sato');

echo "Hello, I'm $name", PHP_EOL;
foreach ($flat as $room_no => &$name) {
// $name = &$flat[$room_no]みたいな処理が入ってる(?)
}
// foreachを抜けても$nameは$flatの最後の要素、$flat[201]への参照を持っている

foreach ($flat as $room_no => $name) {
// $name = $flat[$room_no]みたいな処理が入ってる(?)
// $nameは$flat[201]と同じところを指しているので
// $nameと$flat[201]の値が、$flat[$room_no]の値で上書きされていく
echo "room #$room_no: $name", PHP_EOL;
}
echo "Hello, I'm $name", PHP_EOL;

# Output:
# Hello, I'm hanachin
# room #101: Kato
# room #102: Yoshida
# room #201: Yoshida
# Hello, I'm Yoshida
# --------
?>


解決するためにはforeachでリファレンスを使ったら必ずその直後でunsetします。



<?php
$name = 'hanachin';
$flat = array(101 => 'Kato', 102 => 'Yoshida', 201 => 'Sato');

echo "Hello, I'm $name", PHP_EOL;
foreach ($flat as $room_no => &$name) {
}
unset($name); // 参照を削除

foreach ($flat as $room_no => $name) {
echo "room #$room_no: $name", PHP_EOL;
}
echo "Hello, I'm $name", PHP_EOL;

# Output:
# Hello, I'm hanachin
# room #101: Kato
# room #102: Yoshida
# room #201: Sato
# Hello, I'm Sato
# --------
?>


「foreach ($a as $k => $v) {}の$kと$vがforeachの中だけのスコープを持っていて、foreachの外の変数に影響及ぼさないと嬉しいのになぁ」と思いました。まる。


参考


PHP: foreach - Manual


PHP: 変数のスコープ - Manual