VisualWorksNC7.8とMySQL5.5.15との接続にはまる(Mac OSX Lion)

brew install mysqlMySQLインストールしたら64bitのlibmysqlclient.18.dylibだから、VisualWorksMySQLのドライバいれても動かない。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

だとスレッドセーフになるかな?

ScansnapでつくったPDFをiPadで見ると文字がかすれる

同一ファイルをMacPreviewでみると文字がはっきり見えるのに、iPadに移してiBooksやi文庫HDなどで見ると文字がかすれて見えてしまう。なんとかならないものか。

Pharo SmalltalkをiPhoneで動かしてみる。

iPhoneの開発者登録をしておく。iPhoneSmalltalkが動けばと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を開く
設定をSDKiOS4.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,座席番号が書き込まれる。
UnixMacOSXでは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.

あー風呂はいりてー