VisualWorksNC7.8とMySQL5.5.15との接続にはまる(Mac OSX Lion)
brew install mysqlでMySQLインストールしたら64bitのlibmysqlclient.18.dylibだから、VisualWorksのMySQLのドライバいれても動かない。32bitのmysqlダウンロードしてユニバーサルバイナリ作成して解決。どこのサイト見たかなーー?
sudo lipo -create -output libmysqlclient.18.dylib -arch i386 /path/to/i386/libmysqlclient.18.dylib -arch x86_64 /path/to/x86_64/libmysqlclient.18.dylib
でユニバーサルバイナリつくって入れ替え。無事VisualWorksからMySQLにつながったでござる。
VisualWorks(Smalltalk)でのスレッドセーフなシングルトンの生成について
1つしかないインスタンスを生成するメソッド(currentやdefault)を見ると,
Someting class >> current current isNil ifTrue:[current := Something new]. ^current
という感じの記述を見かけるんだけど,これスレッドセーフじゃないよね.
Someting class >> install self initialize Someting class >> initialize current := Someting new.
として,あらかじめ作っておいて
Someting class >> current ^current
だとスレッドセーフになるかな?
Smalltalk-80 Bluebook chapters 26-30をmobiにしてみた
いつのまにか
http://users.ipa.net/~dwighth/smalltalk/bluebook/bluebook_imp_toc.html
で見れなくなってたので、WebArchiveから持ってきて編集してmobi化した。
Kindleで見られる。
Pharo SmalltalkをiPhoneで動かしてみる。
iPhoneの開発者登録をしておく。iPhoneでSmalltalkが動けばとwktk。
開発環境:XCode4 OSは10.6(Snow Leopard)
1.まずソースコードをとってくる。
svn co http://squeakvm.org/svn/squeak/trunk/ pharo
2. SqueakV42.sourcesをとってきて platforms/iOS/vmに入れる
3. PharoV10.sourcesをとってきてplatforms/iOS/iPhoneに入れる
4. platforms/iOS/vm/SqueakPureObjc.xcodeprojを開く
設定をSDKをiOS4.3へBase SDKを10.6に変更。
あとコマンドで
export MACOSX_DEPLOYMENT_TARGET=10.6
が必要かも。
これでシミュレータでは動作するが、実機で動作させようとするとエラーを吐く。
playforms/unix/plugins/SocketPluginsqUnixSocket.cで
#include
をなぜか読みこんでくれないためで、コメントアウトしちゃう。
5. デバイスにインストール
3GSだと重すぎて使いものにならん。iPhone4でもだめかも。
あしたiPadで試してみよう。iPad2で試したいけどありまへん。
ニコ生よくばり席取りちゃんスクリプト
VisualWorks(Smalltalk)でつくった。片っ端から席を取る(予約放送には勝てない)。
セッションは前に書いた記事のように作っておく。
放送を通知するhost,port,threadの組み合わせは1万回くらいhttp://live.nicovideo.jp/api/getalertinfoにアクセスして重複をのぞいた結果、以下の組み合わせが残った。alert.txtに保存しておく。
twr01.live.nicovideo.jp,2525,1000000000 twr01.live.nicovideo.jp,2526,1000000002 twr01.live.nicovideo.jp,2527,1000000004 twr01.live.nicovideo.jp,2528,1000000006 twr01.live.nicovideo.jp,2529,1000000008 twr01.live.nicovideo.jp,2530,1000000010 twr01.live.nicovideo.jp,2531,1000000012 twr01.live.nicovideo.jp,2532,1000000014 twr01.live.nicovideo.jp,2533,1000000016 twr01.live.nicovideo.jp,2534,1000000018 twr02.live.nicovideo.jp,2525,1000000001 twr02.live.nicovideo.jp,2526,1000000003 twr02.live.nicovideo.jp,2527,1000000005 twr02.live.nicovideo.jp,2528,1000000007 twr02.live.nicovideo.jp,2529,1000000009 twr02.live.nicovideo.jp,2530,1000000011 twr02.live.nicovideo.jp,2531,1000000013 twr02.live.nicovideo.jp,2532,1000000015 twr02.live.nicovideo.jp,2533,1000000017 twr02.live.nicovideo.jp,2534,1000000019
Workspaceで以下のプログラムを実行。log.txtにはプロセスの番号,放送URL,座席番号が書き込まれる。
UnixやMacOSXではtail -f log.txtとやって0番がとれたのをにやにや見る。Corei7のMac Book Proだと上に書いた20個のスレッドにアクセスしても大丈夫だったけどMac Book Airだと2個が精一杯だった。計算機の性能にあわせてalert.txtの個数変えてね。一個だけにしておくのが効率いいのかな?それにしてもこのプログラムもっとなんとかならんもんかな。
log := 'log.txt' asFilename writeStream. requestBlock := [:host :port :thread :num | [| socket stream query | socket := SocketAccessor newTCPclientToHost: host port: port. stream := socket readAppendStream. query := ''. stream nextPutAll: query; nextPut: (Character value: 0); commit. stream upTo: (Character value: 0). [stream atEnd not] whileTrue: [| dataStream lvNum reply parser parser2 contents xmlDoc request response xmlDoc2 user seetno no closedFlag requireComunityMemberFlag chatFlag unknownErrorFlag notfoundFlag cl| reply := stream upTo: (Character value: 0). parser := XML.XMLParser new. parser validate: false. xmlDoc := parser parse: reply readStream. dataStream := xmlDoc root elements first text readStream. lvNum := dataStream upTo: $,. dataStream upTo: $,. request := HttpRequest get:( 'http://watch.live.nicovideo.jp/api/getplayerstatus?v=lv' , lvNum). cl := HttpClient new. request userAgent:'vw'. response := cl executeRequest: request. response charset: 'utf-8'. parser2 := XML.XMLParser new. parser2 validate: false. contents := response contents. closedFlag := contents findString: 'closed' startingAt: 1. requireComunityMemberFlag := contents findString:'equire_community_member' startingAt: 1. chatFlag := contents findString: 'chat' startingAt: 1. unknownErrorFlag := contents findString: 'unknown' startingAt: 1. notfoundFlag := contents findString: 'notfound' startingAt:1. (((( requireComunityMemberFlag == 0 and:[chatFlag == 0]) and:[unknownErrorFlag == 0]) and:[notfoundFlag == 0]) and:[closedFlag == 0]) ifTrue:[ xmlDoc2 := parser2 parse: (contents readStream next ;yourself). user := (xmlDoc2 root elementsNamed:'user') first. seetno := (user elementsNamed:'room_seetno') first. no := seetno elements first. Processor yield. log nextPutAll: num; nextPutAll:','; nextPutAll: 'http://live.nicovideo.jp/watch/lv', lvNum; nextPutAll: ','; nextPutAll: no printString; cr.]]]]. readStream := 'alert.txt' asFilename readStream. name := 1. blocks := OrderedCollection new. [readStream atEnd] whileFalse:[ | host port thread args| host := readStream upTo:$,. port := readStream upTo:$,. thread := readStream upTo: Character cr. args := Array new:4. args at: 1 put: host. args at: 2 put: port asNumber. args at: 3 put: thread. args at: 4 put: name printString. blocks add:(requestBlock valueWithArguments: args). name := name + 1]. processes := blocks collect:[:block | block newProcess ]. processes do:[:process | process resume].
止めるときには次を実行
processes do:[:process | process terminate]. processes := nil. log close.
あー風呂はいりてー