æ©ããªãïŒ ã¯ããŒã«ããŠããããã§ãã
-å倧ãªåèš
ç§ã¯ãã€ãäž»ã«ããã«ã¡ã¯ãšèšãããã«æããããŠããã®ã§ãããã«ã¡ã¯ã ä»æ¥ã¯ã人çã®ç¹å®ã®æéã«çµéšããåµé çãªïŒãããŠããã§ã¯ãªãïŒèŠçãèŠãã¿ãçã¿ã«ã€ããŠè©±ããŸããããããããžã§ã¯ããšåŒã³ãŸãã æåã¯JavaScriptïŒnode.jsïŒã«ãããŸããããçŸåšã¯ScalaïŒPlayïŒã«ãããŸãã ç§ã¯èŠ³å¯å¯èœãªå®å®ã§æã䞻芳çãªæªå ã®äžäººã§ãããšããã«èšããªããã°ãªããªãã®ã§ãå°æ¬ãããèªè ã¯éåžžã«ææ§ã«ãããã€ãã®ã¿ãŒã³ã声æãããã³ãã®ãããªä»ã®ãã®ãç¥èŠã§ããŸãã èŠããã«ãç§ã¯èŠåããã ãããŠããã1ã€å°ããªèŠæããããŸãããã§ã«èšäºãèªã¿å§ããŠããå Žåã¯ãæ¥ãã§ã³ã¡ã³ããæžããŠãã ããã èªã㧠ç§ã¯ããŒã¹ãããã§ã¯ãªããçå®ãèªã£ãŠããŸãã ãããŠãäžè¬çã«ãç§ã¯äœããã®åœ¢ã§è«äºã®çã«ãªã£ãŠããåé¡ã®ã»ãšãã©ãã¹ãŠãäœããã®æ¹æ³ã§èª¬æããŸãã
ããããŒã°
ãããããŸã第äžã«ãç§ã¯å°ãäœè«ããããŠãç§ãäœãããã®ãããããŠãããã©ã®ãããå§ãŸã£ãã®ãã説æããŸãã
çŽ1幎ååãç§ã¯èªåã®æè¡å€§åŠã§è«æã®ãããã¯ãéžæããããšã«çŽé¢ããŸããã ãã¡ãããæŽè»çšã®äžè¬çãªWebãµã€ããCoffeehouse Webãµã€ãã®æ°ãããã¶ã€ã³ã®å¥ã®ã³ã³ã»ããããŸãã¯åæ§ã®äœãã§èªåãæ£åœåããããšãã§ããŸãïŒã¡ãªã¿ã«ããããã¯å®éã®åæ¥ãããžã§ã¯ãã§ãããç·åŒµããŸãããçç¥ããŸãïŒã ããããç§ãã¡ã¯é åºã§ããããã®åéã®å°é家ã§ãããããŸãïŒ ç°¡åãªæ¹æ³ãšäœãšãäœãšããæ¢ããŠããããã§ã¯ãããŸããã
ãã®æãŸã§ã«ãç§ã¯ãã§ã«çŽ3幎ã®å®åçµéšãããã6ã7幎ã¯ããã°ã©ãã³ã°ãç¹ã«Webã§çãå°œããŠããŸããã ãããã£ãŠãç§ã®åã«å®è£ ã«é¢ãã質åã¯ãããŸããã§ããã æ®ãã®ãããã¯ãã€ãŸãåããããžã§ã¯ãããããŸããã å°å ã®äººã¯èŠãã¿ãéããŠã®éçºã«é¢ãã楜ããèšäºãç¥ã£ãŠããã¹ãã§ãã
ã§ãããããã®æãäžç·ã«ä»äºããããã仲éãšæ¬¡ã®YPãå匷ãããããŠãæ¬åœã«èŠãã¿ãŸããã pastebinã«äŒŒãããŒã«ãå¿ èŠã§ããã ïŒéä¿¡æžã¿-ãªã³ã¯ã®ã³ããŒ-å ±æïŒãšããŠã¯èªæã§ãããããã§ãGoogle Docsãããã䜿çšããŠããŸããã€ãŸããåæã«ã³ãŒããç·šéããŠããŸãã åæãã-誰ãã暪æ ã«ã«ãŒãœã«ã眮ãã2åã®ããŒã¹ãããŒã¯ã§ãããä¿®æ£ããæ¹æ³ãèŠãã ãã§ã¯ãŒã«ã§ãã ãŸããæ¯ååãã³ãŒããè€è£œããŠãªã³ã¯ãå€æŽãããããé«éã§ãã çã¿
ãããŠãç§ã¯ãããã®ãµãŒãã¹ãæ¢ããŠãããã®ããªãã®ã€ã³ã¿ãŒããããé§ãå·¡ããŸããããããŠ...ã¯èŠã€ãããŸããã§ããã ãã¡ãããEclipseãSublimeãªã©ã®ã»ãã«ãã©ã°ã€ã³ãç¥ã£ãŠãããã¹ã¿ã³ãã¢ãã³ãœãªã¥ãŒã·ã§ã³å šäœã«ã€ããŠãç¥ã£ãŠããŸãã ããããããŒã¹ããã³ã»ã©åçŽãªãã®ã¯èŠã€ãããŸããã§ããã ãããã£ãŠãç§ã®ãããžã§ã¯ãã¯ã«ãŠã³ãããŠã³ãéå§ããŸããã
第1ç« JavaScript
ããããŒã°ãããäœæ¥ã®çã声æãå¿ èŠãªãµãŒãã¹ãšã¯äœãããããŠãããã©ã®ããã«å®è¡ãã¹ããããã§ã«åœ¢æããŠããå¯èœæ§ããããŸãã
倧ãŸãã«èšãã°ããŠãŒã¶ãŒãã£ããã«ãŒã ãããã€ããããŸãããã£ããã®ä»£ããã«ãã¿ããªããã£ãšèŠãŠããã³ãŒãããããŸãã ã©ããã£ãŠïŒ èŠããã«-ç§ã¯ãã©ãã·ã¥ã奜ãã§ã¯ãªããç§ã¯ãŠã§ããœã±ããã欲ããã
åœæãç§ã¯PHPã«åºå·ããŠããŸãããããã®äžã§WebSocketãµãŒãã¹ãäœæããŸãããå šäºéæ¥ç¶ã¯ãç¡éã«ç¶ãå¯èœæ§ããããå°çãžã®çŽæ¥ã®éã§ãã ãã®ãããWSãµãŒãã¹ãšããŠã®node.jsã«æ³šç®ããéçãçæããŠãããäžããŸããã ãããŠãããªãã¯äœãç¥ã£ãŠããŸããïŒ ããã¯ãããã£ãã æ°æ¥ã§ãããã¿ã€ããæããŸããã ãã¹ãŠãããŸããããŸãã ããããŠããã¯èšèã§è¡šããªãæ°æã¡ã§ããã ãŸãã§åŒŠçè«ãå®å šã«å®çŸããããã§ãã ãŸãã¯ããã©ãã¯ããŒã«å ã®æ å ±ãæ¶ããå Žæãæšæž¬ããŸããã ãŸããããªãã¯ç§ãç解ããŠããŸããïŒ ãããŠãWebSocketããããã·ã§ããnginx'aãªãªãŒã¹ããªãªãŒã¹ããŸããã
ãªã£ãã¿
// , . . var sockjs_im = sockjs.createServer(sockjs_opts); sockjs_im.on('connection', function(c) { // sender.setValidTimeout(c); // c.on('data', function(message) { sender.process(message,c); }); c.on('close',function() { connection.removeConnection(c); }) }); var server = http.createServer(); server.addListener('upgrade', function(req,res){ res.end(); }); sockjs_im.installHandlers(server, { prefix: config.get("path") }); exports.startWSServer = function() { server.listen(2410, '0.0.0.0',function() { console.log(' [*] Listening WS on 0.0.0.0:2410' ); }); }
ããããããžãã¹ã«æ»ããŸãã ç§ã¯ãã®ãã³ããŒãã€ããã§åšãã®ãã¹ãŠãå©ãå§ããããã§åœŒãã«ãã§ã«ç解ãããŸãã-誰ãéã§èª°ãã©ã¯ããªã®ãã 圌ã¯æãæµè¡ã«ææãªãã¯ãããžãŒãæ¡çšããŸããïŒWSæ¥ç¶ã®ã¯ã©ã€ã¢ã³ããµãŒããŒãšããŠã®SockJSãããŒã¿ããŒã¹ãšããŠã®MongoDBãã¯ã©ã€ã¢ã³ãã®ãšãã£ã¿ãŒãšããŠã®Ace Editorãããããç²ç®ã«ãããã€ã³ãã£ã³ã°ãããžãã¯ã®èšè¿°ãéå§ããŸããã
ããããç§ã¯å°ããªã¡ã¢ãããŸã-ãããžã§ã¯ãã¯åæ¥åŒã§ããã®ã§ãç§ã¯è¿ éãã€å®äŸ¡ã«ããããŠããã«ãã¹ãŠãããªããã°ãªããŸããã§ããããç§ã¯ä»äºãããŠäœããæž¡ãå¿ èŠããããŸããã
1ãæåŸãå¥ã®ãšãã«ã®ãŒã®çŒ¶ãã§ããåŸãç§ã¯ã¹ã¯ãªãŒã³ããèµ€ãç®ãåŒãè£ããããã«æ»ã¬ã»ããããã¢ã³ã¹ã¿ãŒãã¯ãªãŒãã£ãŒãçãŸããããšã«æ°ä»ããŸããã ããããæ©èœãã倱æããããšãªãã ã»ãšãã©ãã¹ãŠã®æ©èœãæºåã§ããŸããã ãããããã®ä»çµã¿ã¯ãã°ãããã£ãã ç§ã¯èŽåœçãªééããç¯ãããããã¿ã€ããæžãçŽããŸããã§ããã äœãäžããŸããã ã³ãŒãã¯è€éã§åé·ã«ãªããŸããã
ãã®ç¬éããããããžã§ã¯ãã®ä»äºã¯æ·åã«å€ãããŸããã æ°ããæ©èœãŸãã¯æ©èœãè¿œå ããã«ã¯ãå€ãã®åŽåãå¿ èŠã§ããã Sisyphusã®ããã«æããŸãããç³ã ããæ£æ¹åœ¢ã§ããããŸããã æ²æšã
è«ççãªè³ªåã¯-äœã«ã€ããŠè©±ããŠããã®ã§ããïŒ ä»¥äžã«çããªã¹ãã瀺ããŸãã
- ã³ãŒã«ããã¯å°ç
- ãããã¿ã€ãã䜿çšããŠJSã§OOPãèšè¿°ããã
- ...ãããã£ãŠãæœè±¡åãããæœè±¡åã®è©Šã¿
- ...ãããŠãããªããæœè±¡åãããŠããéã7çªç®ããã§ã«æ¥ãŠã圌ã®æ¯èŠªãã³ãŒã«ããã¯å°çã®èŒªãããªãã¯åaspè ãšãœããã€ããšæ¡æããŸãïŒãã³ããæ£ããã£ãïŒïŒ
ãããŠã7çªç®ã®ãµãŒã¯ã«ã®ãã«ããå®ã£ãŠèšãããã¿ãŠãã¹ãæ¥ãŸãïŒ
- ãããç·ã ãŸããããªãã¯èªåã§ã°ãã§ãã 圌ã¯æªéãæžãããããªãã¯ããªãã®è¶³ãæãã圌èªèº«ã¯èªããã ããªãã®åé¡ã¯äœã§ããïŒ
ãããŠãããªãã¯ç§ãçããã®ãç¥ã£ãŠããŸããïŒ ããã¯ãã¹ãŠJavaScriptã§ãã ã€ãŸãã誀解ããªãã§ãã ãããIQ>>> infinityã§ç§ããšãŠããã¥ãŒãã§ãµããµãããŠãããšããæå³ã§ã¯ãããŸããã ã€ãŸããèšèªèªäœã¯ ãããã§ã¯ãªãããã®ããã«æžãããšã奚å±ããŠããŸãã ãããããããªäžçš®ã®èïŒ
- ãããåŒæ°ã§3çªç®ã®ã³ãŒã«ããã¯ãããã§ããã«åºå·ããŠãã ããã
ãããŠãç§ã®ç®ã®åã®ãã®ãããªé·ãèµ€ãèã
ããã¯ãã¹ãŠãã®ãããªãã®ã«èŠããŸãã
/** * . - ... */ var loadSession = function(sessid, callback) { if(typeof sessid != 'string') return; var sess = sessions.getSession(sessid); sess.setLoadCallback(callback); } ... /** * , , , . * -, . */ loadSession(msgObj["sessid"], function(sess) { var r = rooms.getRoom(msgObj["room"]); r.setLoadCallback(function() { r.addUser(connection, sess, function(newUser) { if(newUser!==false) { var outMsg = { action: "newUser", data: newUser } r.broadcast(connection, outMsg); r.write(connection,{ action: "join" }); }else{ error(connection,{ error:true, errsmg: "something went wrong" }) } }); }); }); ...
ããããããã¯ãã¹ãŠã®ãšãã«ã®ãŒã§ãããããã®ããããã¿ãŠãã¹ã¯ç§ã«æ¥ãŸããã§ããïŒã¯ããŒã«ãããŸããïŒããããã¯äœãèµ·ãã£ãã®ãå€æããŸããã åæ¥èšŒæžã¯åæ ŒããŸããããçãç©ãšåŒã¶ããšãã§ããã°ãçãç©ã¯çãããŸãŸã§ããã
ãã®æªç©ããªãã¡ã¯ã¿ãªã³ã°ããããšãããã¹ãŠãã³ãŒããŒã¹ã¯ãªããã«æžãçŽãããšããããã€ãã®è©Šã¿ã®åŸãç§ã¯ãã®æªéãããè¯ãæãŸã§æšãŠãŠããšãŒãããäžãèµ°ãã«è¡ããŸããã ãããç§ã¯ãšãŠãæ·±ãèœã¡ãŠãéå»ã®æªå€¢ããé ãé¢ããŠèµ°ããŸããïŒ
第2ç« Scala
6ãæãçµéããŸããã ç£ã¯ãã¹ãŠååšããŠããŸããããç§ã¯ãããçµãããããã§ã«çç£äžã«ããããªãªãŒã¹ããããšãæã¿ãŸããã§ããã JavaScriptã³ãŒããéããšãåŒã³åºãé³ã§ååããããã«äœ¿çšãããéå±è£œã®æŽé¢åšãç·æ¥ã«å®è¡ããå¿ èŠããããŸããã
ãããŠãã€ã³ã¿ãŒãããã§è¿·åã«ãªã£ãŠãPlay Frameworkãµã€ãã«è¡ãçããŸããã ãµã€ãã§ç§ãæ¹ãã€ããé ããããã®ãèŠããŠããŸããããããã¯éèŠã§ããïŒ ãã®çµæã1æ¥åŸã«ãã¬ãŒã ã¯ãŒã¯ãæãäžããæåã®ã¢ããªã±ãŒã·ã§ã³ãäœæããcoursera.orgã®Scalaã³ãŒã¹ã«ç»é²ããŸããã
ç¹ã«æåã¯ç°¡åã ã£ããšã¯èšããŸããã ãã¡ããããã€ãœã³ãããã¯ãã£ãšã·ã³ãã«ã§ãããQt / C ++ãšJavaã®ããã¯ã°ã©ãŠã³ããæã£ãŠããã®ã§ãå°ãªããšãèŠç¹ã«ã€ããŠã¯ãããæ£ãããªãçŽ æ©ãèŠã€ããŸããã æé»ã®å€æãšãã©ã¡ãŒã¿ãŒãå³ããããã«ãco / counter / invarianceãªã©ã®ãããªãã®ã¯ãGoogleã¹ãã«ã掻çšããŠããŸããŸãªäŸãšããã¥ã¡ã³ããæ€çŽ¢ãããã³ãããã®ã©ããã§èµ·ãã£ãŠããããšã®å šäœåãææ¡ããå¿ èŠããããŸããã ããã§ãããã°ããã®éãç§ã¯éŠ¬é¹¿ããããŒãã®ããã«æããŸããããããã¯æ£åžžã§ãããšããæèŠããããŸãã
ãããŠä»ãå°ãã¬ãããã¿ãæã£ãŠãç§ã¯Playãwebsocketã§ãããã©ã®ããã«è¡ããããèŠãããšã«ããŸããã ãããŠãããã§ç§ã¯æ°·æ°Žã®æµŽæ§œã®ããã«æ³šãããŸããã æåã®åå¿ã¯ã·ã³ãã«ã§ãã-WTF ??? ãã¥ãŒãã§æé ãªäŸ¡æ Œã®ãœãªã¥ãŒã·ã§ã³ã¯ã©ãã«è¡ããŸãããïŒã»ãŒäœã¬ãã«ã®Iteratee / Enumerateeãåãããã®æ©èœçãªããŒãã³ã¢ãšã¯äœã§ããïŒ ã¯ããJavaScriptã®å€±æãšã¯äœã®é¢ä¿ããããŸããã
push
ãš
onMessage
è¿ããŠãã ããïŒ
ãã£ã³ãã«ãããªããŠ
def index = WebSocket.using[String] { request => // Just consume and ignore the input val in = Iteratee.consume[String]() // Send a single 'Hello!' message and close val out = Enumerator("Hello!").andThen(Enumerator.eof) (in, out) }
ããããããŸãã«ãåçŽãªãœãªã¥ãŒã·ã§ã³ã®èŠãçµéšãââæããããŠãç§ã¯ããããããåã³åãäžããããšã«æ±ºããŸãã...ãããããã³ããŒã§ã¯ãããŸããã Googleã ãã®çµæãå¿«é©ãªã¢ãããŒããçºèŠãããŸãã
Concurrent.unicast
val promiseIn = Promise[Iteratee[String, Unit]]() val out = Concurrent.unicast[String]( onStart = onStart(promiseIn, r, userSession), onError = onError ) (Iteratee flatten (promiseIn.future), out) ... private def onStart(promiseIn: Promise[Iteratee[String, Unit]], ...): (Channel[String] => Unit) = { ... (ch: Channel[String]) => { val channel = new ChannelContainer(ch) for (optUserConnection <- isConnectedF(r, channel)) yield { optUserConnection match { case Some(userConnection) => { val in = Iteratee.foreach[String] { MessageController onMessage (r, userConnection, channel) //bind handler for room and this connection } map { MessageController onDisconnect (r, userConnection, channel) //handler for disconnect } promiseIn success in //success promise and fill it with iteratee } case None => channel eofAndEnd //in case of some troubles with new user creation - close connection } } } }
ã¯ããåæããŸãã ãŸã ããŸããã¥ãŒãã§é¢åã§ã¯ãªãããã«èŠããŸãããã¡ãã»ãŒãžã³ã°çšã«äœæãããæšæºãã£ãã«ã䜿çšããŠããããã®ãã£ãã«ãã©ãããŒã«ããã·ã¥ããã¡ãã»ãŒãžãšãšãã«ä¿³åªã«è»¢éããããšãã§ããŸãã
Scalaã®ã¢ã¯ã¿ãŒã ç§ã®å¿ã®ãã«ã³ã®åã³ã æé«ã®ãã©ãã€ã ãšãŽã¡ïŒ ãŸãããŸãã¯ç¢ºãã«ç§ã®ç®çã«å¿ èŠãªãã®ã éšå±ã¯ä¿³åªã§ãããéšå±ã®ç®¡çè ã¯ä¿³åªã§ãã ãããŠã顧客ã§ãã俳åªã§ãã è«ççã«ãŠãŒã¶ãŒéã®ã¡ãã»ãŒãžã³ã°ã®ã€ããªãã®ãŒã«æµã蟌ã¿ãŸãã ãšããã§ãPlayã®éçºè ããã®ãããã¯ãèããŠãããæè¿ãªãªãŒã¹ãããããŒãžã§ã³2.3
WebSocketæ¥ç¶ãã¢ã¯ã¿ãŒã«ãªããŸãã
import play.api.mvc._ import play.api.Play.current def socket = WebSocket.acceptWithActor[String, String] { request => out => MyWebSocketActor.props(out) }
import akka.actor._ object MyWebSocketActor { def props(out: ActorRef) = Props(new MyWebSocketActor(out)) } class MyWebSocketActor(out: ActorRef) extends Actor { def receive = { case msg: String => out ! ("I received your message: " + msg) }
ãããŠãå®å®ãããªããèããŠããã®ã¯çŽ æŽãããããšã§ãã ç§ããã®ä¿¡å·ã¯ãè¹ã®ãããªè¶ã®ææã§ãããããå 幎ã®éã«ããè¡šé¢ãããŸã åå°ããæ»ã£ãŠããŸããã ã¯ã©ã³ã¿ã ã¯æ··ä¹±ããã¢ãªã¹ãšããã¯ãäºããèŠã€ããŸããã ãããŠãç§ã¯å¹³åãèŠã€ããŸããã
ãªãã§ïŒ ã»ãšãã©ã®å ŽåãScalaã¯äœãééã£ãããšãããå Žåãããªããããããšã®ããã«èŠãŠããã ãã§ãã 圌女ã¯ããªãã«èšã£ãŠãããŸãïŒ
-ã¬ã€ãç§ã¯ã¢ããã®åœ¢ã§ãã€ãã£ãã®FutureãµããŒããæäŸããJSONã¡ãã»ãŒãžãå¿ èŠãªã±ãŒã¹ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã«ãã£ã¹ãããå€ãã®ç¹æ§ãç¶æ¿ããæ©èœãæäŸããŸããç§ã¯ããªãã確èªããŸã ãããæ£ããè¡ãããããã¿ãŠãã¹ã§å°çã«æ»ã£ãŠãã ããã
å³æ Œã ãå ¬æ£ãªä»²éã ã²ããçããããã€ãŒã³ãã«ã¯ããã°ã©ãã³ã°ã ãããScalaãbiaaatchïŒ ãããŠãããŒãã£ã³ã»ãªãŒãã«ã¹ããŒèªèº«ãããªããåŸãããèŠã€ããŠããŸãã
ãšãããŒã°
ããã§ã¯ããã®ãããªæ··
æåã®ãã® ã èšèªãæ¯èŒããŸããã ãã¹ã¿ãä¿åããŸãã ScalaãšJavaScriptãæ¯èŒãã-ããã¯ãã©ã€ãªã³ãšãã°ãã¡ããã®ã±ãŒããæ¯èŒããæ¹æ³ã§ãã ã¯ãããã°ãã¡ããã®ãã€ãé£ã¹ãããšãã§ããŸãã ããããã©ã€ãªã³ã¯ããããããªãã ããããã©ã€ãªã³ã¯ããªããé£ã¹ãããšãã§ããŸãã ãããã¯ç°ãªãã¿ã¹ã¯ã®ããã®ç°ãªãèšèªã§ãã Scalaããã³ããšã³ãã¯èª°ãäœæããŸããïŒ
äºçªç® ã ç¹å®ã®åé¡ã解決ããããã«äœ¿çšãããèšèªãšãã©ãããã©ãŒã ãæäŸããæ©èœããŸãã¯ãããã¢ãããŒããæ¯èŒããŸãã 玳士ã§ãããã³ãŒã«ããã¯ã¯é©åããŸããïŒ ããã¯ã¯ãœè©æ±ºã§ãã
10åã®Futureãã1è¡ãäœæããŠããã®å®è¡ãåŸ ã€ããšãã§ããŸãã Futureãã¢ããã§ãããšããçç±ã ãã§ãèšèªã®ç²Ÿç¥ã§ã¯ããã¹ãŠãã·ã³ãã«ã§èªç¶ã«èŠããŸãã ã³ãŒã«ããã¯ã«ã€ããŠã¯ãçµäºããé¢æ°ã®æ°ãã«ãŠã³ãããããæ¬æ ŒçãªDeferred / Promiseã«ãªãã©ãããŒãäœæããå¿ èŠããããŸãã ã¯ããã¯ããJavaScriptçšã®ãã®ãããªã©ã€ãã©ãªã®ååšã«ã€ããŠç¥ã£ãŠããŸãã ãããããããã¯åãã³ãŒã«ããã¯ã®åãªãè¥å€§åããã©ãããŒã§ãã éãã
3çªç® ã JavaScriptãä»ãããããŸãæžããŸããïŒ ééããªãã èŠãç®ãåäœãç°¡åã ã£ããããããŸããã 1ã€ã®ã¿ã€ãã®åé¡ã解決ããçµéšã¯çµéšã§ããã飲ãããšã¯ã§ããŸããã ScalaãããããŸãããã§ããããïŒ äºå®ã§ã¯ãããŸããã ã¯ããScalaã§ã¯ãããã€ãã®å Žæã§ããã«å€ãã®ã³ãŒããèšè¿°ããå¿ èŠããããŸãããæ°ãã€ããŠãã ããïŒ JSONãããªããžã§ã¯ããååŸãã1ã€ã®ã¡ãœããã«å¯ŸããŠäœçŸãã®ãã¹ããèšè¿°ããå¿ èŠã¯ãããŸããããã¹ãŠãæå³ãããšããã«åäœããããšã確èªããŸãã ããçš®ã®ã¹ã¯ãªããããã£ã¯ãé åã®æååãæ°å€ã®é åãªã©ã眮ãæããŸããã§ããã ç§ã«ãšã£ãŠã¯ãèšèªããã©ãããã©ãŒã ãã³ã³ãã€ã©ãŒã«ãã£ãŠè¡ãããŸãã
4çªç® ã Scalaã¯è€é ã Scalaã¯è€é ã Scalaã¯è€éã§ãã æ°å人ã äœãšãäœãšãã äœãé£ãããç¥ã£ãŠããŸããïŒ ãã®ã³ã³ããã¹ããšãjavascriptå¿è ã®ç¥çµç¯ã絶ããæ©ãŸããŠããä»ã®äœçŸãã®åŽé¢ã«çæããŠãã ããã çå£ã«ãJSeã§å€æ°ã®ããžãã¯ãæã€å€§èŠæš¡ãªãããžã§ã¯ããæžãã«ã¯ãScalaãããã¯ããã«å€§ããªå°é家ã§ããå¿ èŠããããŸãã ãå°»ã§æããŸããã æ¯æ¥ãã®äžå¹³çãªæŠãã«åå ããŠãã人ãã¡ãå°éããŠãã ããã ããªãã¯ã¯ãŒã«ã§ãåè«ã§ã¯ãããŸããã JavaScriptã¯ç°¡åã§ã¯ãããŸããã
ããããç§èªèº«ã®ããã«ãç§ã¯èŠããŸãªãããšã«æ±ºããŸããã ãªãã§ïŒ