S H O Y O S H I D A
S O R A B I T O I N C
Smalltalk ?
3 1 M A R C H 2 0 1 7
Smalltalk
Smalltalker
https://fossbytes.com/most-loved-and-most-hated-programming-languages/
Which Are The Most Loved and Most Hated Programming Languages | 2017
Smalltalker
Web Seaside
Develop in Pharo, Run on Javascript
PharoJS
• https://pharojs.github.io/
• http://smalltalkhub.com/#!/~noury/PharoJS
• ESUG 2015
• Pharo JavaScript
Enterprise Pharo
( )
Smalltalk
Twitter
• Smalltalk All the Time & Everywhere
PharoJS
PharoJS
PharoJS
PharoJS
•
• Smalltalk
•
PharoJS
: Teapot
Smalltalk
Gofer it
smalltalkhubUser: 'noury' project: 'PharoJS';
configurationOf: #PharoJS ;
loadBleedingEdge.
C O D E + T E S T M O D E L
Pharo Pharo
counter := MyCounter new.
counter count.
counter increment.
counter count.
C O D E + T E S T I N T E G R AT I O N
C O D E + T E S T I N T E G R AT I O N
MyCounterController MyCounterBrowserApp
Model Controller
C O D E + T E S T I N T E G R AT I O N
MyCounterController MyCounterBrowserApp
Model Controller
MyCounterController
Object subclass: #MyCounterController
instanceVariableNames: 'counter countDisplay'
classVariableNames: ''
package: 'PharoJS-Demo'
MyCounterController
MyCounterController>>increment
self counter increment.
self updateDisplay
MyCounterController>>reset
self counter reset.
self updateDisplay
MyCounterController>>updateDisplay
self countDisplay innerHTML: self counter count
MyCounterBrowserApp
PjFileBasedBrowserApp subclass: #MyCounterBrowserApp
instanceVariableNames: 'counter controller'
classVariableNames: ''
package: 'PharoJS-Demo'
MyCounterBrowserApp
MyCounterBrowserApp>>initialize
super initialize.
counter := MyCounter new.
controller := MyCounterController new.
controller counter: counter.
controller countDisplay: self countDisplay.
self resetButton addEventListener: #click block: [ controller reset ].
self incrementButton addEventListener: #click block: [ controller increment ]
MyCounterBrowserApp
MyCounterBrowserApp>>incrementButton
^ self domElementAt: 'incrementButton'
MyCounterBrowserApp>>resetButton
^ self domElementAt: 'resetButton'
MyCounterBrowserApp>>countDisplay
^ self domElementAt: 'countDisplay'
MyCounterBrowserApp
MyCounterBrowserApp>>(class)appClasses
<pharoJsSkip>
^super appClasses, {MyCounter. MyCounterController}
MyCounterBrowserApp>>(class)appJsSubFolder
^'js'
JavaScript
C O D E + T E S T I N T E G R AT I O N
MyCounterController MyCounterBrowserApp
Model Controller
MyCounterBrowserApp setUpAppFolder.
MyCounterBrowserApp appFolder.
HTML
C O D E + T E S T I N T E G R AT I O N
<!DOCTYPE html>
<meta charset="utf-8" />
<head>
<title>MyCounter</title>
</head>
<body>
<div class="container">
<div id="countDisplay" class="countText">0</div>
<button id="resetButton" class="resetButton">Reset</button>
<button id="incrementButton" class="incrementButton">Increment</button>
</div>
<script language="javascript" type="text/javascript" src="js/index.js"></script>
</body>
</html>
HTML
PjTranspiler
PjTranspiler convertToJs:[ 1+1 ] .
jsString := PjTranspiler convertToJs:[ [ 1+ 1 ] ].
jsString := PjTranspiler convertToJs:[:x | x + 1 ].
jsString := PjTranspiler convertToJs:[ [:x | x + 1] value:2 ].
PjTranspiler convertToJs: MyCounter.
Smalltalk JavaScript
MyCounterBrowserAppTest
PjWebAppTestCase subclass: #MyCounterBrowserAppTest
instanceVariableNames: 'application countDisplay incrementButton
resetButton'
classVariableNames: ''
package: 'PharoJS-Demo-Tests'
MyCounterBrowserAppTest
MyCounterBrowserAppTest>>setUp
super setUp.
application := self currentApp.
countDisplay := application countDisplay.
resetButton := application resetButton.
incrementButton := application incrementButton.
MyCounterBrowserAppTest>>currentApp
self subclassResponsibility
MyCounterBrowserAppTest
MyCounterBrowserAppTest>>testClickOnIncrementButtonIncreasesCountAn
dUpdatesDisplay
1 to: 10 do: [ : expectedCount |
incrementButton click.
self assert: countDisplay innerHTML equals: expectedCount asString
]
MyCounterBrowserAppTest
MyCounterBrowserAppTest>>(class)appClass
^MyCounterBrowserApp
MyCounterBrowserAppTest>>(class)isAbstract
^self == MyCounterBrowserAppTest
MyCounterBrowserAppTest>>(class)targetPlatforms
^{PjSafari . PjGoogleChrome. PjFireFox. }
T E S T P O R TA B I L I T Y
MyPharoCounterBrowserAppTest
MyCounterBrowserAppTest subclass: #MyPharoCounterBrowserAppTest
instanceVariableNames: ''
classVariableNames: ''
package: 'PharoJS-Demo-Tests'
MyPharoCounterBrowserAppTest>>currentApp
^MyCounterBrowserApp start.
MyPharoCounterBrowserAppTest
MyCounterBrowserAppTest subclass: #MyPharoCounterBrowserAppTest
instanceVariableNames: ''
classVariableNames: ''
package: 'PharoJS-Demo-Tests'
MyPharoCounterBrowserAppTest>>currentApp
^ self evalBlock: [MyCounterBrowserApp currentInstance]
PjBridge
bridge := PjBridge startOn: 9001 title:'test'.
bridge clientTitle.
bridge evalBlock: [1+2].
bridge evalBlock: [|x| x := 6 * 7].
bridge loadClass: MyCounter.
bridge evalBlock: [
|counter|
counter := MyCounter new.
counter increment.
counter count.].
bridge stop.
JavaScript Interpreter
• PharoJS Smalltalk
• Pharo JavaScript

今時なウェブ開発をSmalltalkでやってみる?