上手さんの XP-jp の投稿経由で「目覚まし時計が必要になった Smalltalker の話」

ネタ(なんの?w)に使えそうなので、忘れないうちにメモ。


とりあえず、最初のとっかかりのスクリプトだけ Squeak システムの Smalltalk で。

[[(Delay forSeconds: 15) wait. Time now hours = 3] whileFalse.
30 timesRepeat: [(SampledSound soundNamed: 'warble') playAndWaitUntilDone]] fork


続き。これって意外と便利かも。さっそくキッチンタイマーとして活躍。w
なお、メソッド名や変数名は自分の好みに変えてしまいました。

Object subclass: #AlarmClock
	instanceVariableNames: 'hours minutes ringCount alarm '
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Category-AlarmClock'!

!AlarmClock commentStamp: 'sumim 11/12/2004 23:20' prior: 0!
I'm a simple alarm clock, originally written by Ron Jeffries.

see http://www.xprogramming.com/xpmag/alarm_clock.htm!


!AlarmClock methodsFor: 'accessing' stamp: 'sumim 11/12/2004 21:55'!
bellSound
	^ SampledSound soundNamed: 'warble'
! !

!AlarmClock methodsFor: 'accessing' stamp: 'sumim 11/12/2004 22:05'!
ringCount: anInteger
	ringCount _ anInteger
! !


!AlarmClock methodsFor: 'initialization' stamp: 'sumim 11/12/2004 22:29'!
initialize
	| now |
	now _ Time now.
	self setHours: now hours minutes: now minutes.
	ringCount _ 30
! !


!AlarmClock methodsFor: 'ringing' stamp: 'sumim 11/12/2004 22:06'!
ring
	ringCount timesRepeat: [self bellSound playAndWaitUntilDone]
! !


!AlarmClock methodsFor: 'switching' stamp: 'sumim 11/12/2004 22:25'!
off
	alarm ifNotNil: [alarm terminate]
! !

!AlarmClock methodsFor: 'switching' stamp: 'sumim 11/12/2004 22:25'!
on
	alarm _ [self loop] fork
! !


!AlarmClock methodsFor: 'testing' stamp: 'sumim 11/12/2004 21:47'!
isNowForAlarm
	| now |
	now _ Time now.
	^ now hours = hours and: [now minutes >= minutes]
! !


!AlarmClock methodsFor: 'private' stamp: 'sumim 11/12/2004 22:11'!
loop
	[self isNowForAlarm] whileFalse: [self wait].
	self ring
! !

!AlarmClock methodsFor: 'private' stamp: 'sumim 11/12/2004 20:55'!
setHours: hoursInteger minutes: minutesInteger
	hours _ hoursInteger.
	minutes _ minutesInteger
! !

!AlarmClock methodsFor: 'private' stamp: 'sumim 11/12/2004 21:45'!
wait
	(Delay forSeconds: 15) wait
! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

AlarmClock class
	instanceVariableNames: ''!

!AlarmClock class methodsFor: 'instance creation' stamp: 'sumim 11/12/2004 22:15'!
hours: hoursInteger minutes: minutrsInteger
	^ self new 
		initialize; 
		setHours: hoursInteger minutes: minutrsInteger; 
		yourself
! !


!AlarmClock class methodsFor: 'examples' stamp: 'sumim 11/13/2004 00:33'!
example
	"AlarmClock example"

	| target hours minutes alarm |
	target _ Time now addSeconds: 60.
	hours _ target hours.
	minutes _ target minutes.
	alarm _ AlarmClock hours: hours minutes: minutes.
	alarm on.
	Smalltalk at: #ALARM put: alarm

	"(Smalltalk removeKey: #ALARM ifAbsent: [nil]) ifNotNilDo: [: alarm | alarm off]"
! !


!AlarmClock class methodsFor: 'utilities' stamp: 'sumim 11/13/2004 00:25'!
ringAfterMinutes: anInteger
	"AlarmClock ringAfterMinutes: 3"
	^ AlarmClock ringAt: (Time now addSeconds: anInteger * 60)
! !

!AlarmClock class methodsFor: 'utilities' stamp: 'sumim 11/13/2004 00:27'!
ringAt: aTime
	| alarm stopButton |
	alarm _ AlarmClock hours: aTime hours minutes: aTime minutes.
	stopButton _ SimpleButtonMorph new.
	stopButton labelString: ('Alarm: ', aTime printMinutes, ' (Press me for OFF)') withCRs.
	stopButton target: [alarm off. stopButton delete].
	stopButton actionSelector: #value.
	stopButton openInHand.
	alarm on.
	^ alarm
! !


TestCase subclass: #AlarmClockTest
	instanceVariableNames: 'alarm '
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Category-AlarmClock'!

!AlarmClockTest commentStamp: 'sumim 11/12/2004 23:23' prior: 0!
I'm tests for AlarmClock, originally written by Ron Jeffries.

see http://www.xprogramming.com/xpmag/alarm_clock.htm!


!AlarmClockTest methodsFor: 'test' stamp: 'sumim 11/13/2004 01:49'!
testDelay
	| target hours minutes |
	target _ Time now addSeconds: 60.
	hours _ target hours.
	minutes _ target minutes.
	alarm _ AlarmClock hours: hours minutes: minutes.
	alarm ringCount: 1.
	alarm loop.
	self should: [Time now minutes >= minutes]
! !

!AlarmClockTest methodsFor: 'test' stamp: 'sumim 11/12/2004 22:12'!
testReturn
	| now |
	now _ Time now.
	alarm _ AlarmClock hours: now hours minutes: now minutes.
	alarm ringCount: 1.
	alarm loop.
	self should: [true]
! !