æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.7ï¼»CHAPTER6 ææ ã³ã³ããã¼ã«ã®éè¡å¸«ï¼½â¡
è¨äºã®æ¦è¦
ãæããããã°ã©ã ãã®ï¼»CHAPTER6 ææ ã³ã³ããã¼ã«ã®éè¡å¸«ï¼½ãåèã«ãä¼è©±ã®ä¸ã®åèªã«ãã£ã¦ããã£ã©ã¯ã¿ã¼ã®è¡¨æ ãå¤åãããã£ããããããä½æãã¾ãã
ç®æ¬¡
éçºç°å¢
- OSX 10.11.2 El Capitan
- ããã¹ãã¨ãã£ã¿ï¼ MacVim
- ã¿ã¼ããã«ã¨ãã¥ã¬ã¼ã¿ï¼ Macã¿ã¼ããã«
- ã·ã§ã«ï¼ zsh
- ããã±ã¼ã¸ããã¼ã¸ã£ï¼ Homebrew
- ãã©ã¦ã¶ï¼ Firefox - Ruby 2.0.0p645
- ãã¼ã¸ã§ã³ããã¼ã¸ã£ï¼ rbenv
- Webãã¬ã¼ã ã¯ã¼ã¯ï¼ Sinatra
åèè¨äº
Rubyã®éçºç°å¢æ§ç¯ã¯ããã¡ãã®è¨äºãåèã«ããã¦ããã ãã¾ããã
ããã£ããã ã¦ã
ä¼è©±ã«ãã£ã¦å¤åãããã£ãããããã®ææ å¤ãåç §ãããã£ã©ã¯ã¿ã¼ã®ã¢ãã¡ã¼ã·ã§ã³ã®ç¨®é¡ãå¤åããã¾ãã
ã¢ããªã±ã¼ã·ã§ã³ãã£ã¬ã¯ããªã®æ§æ
~/programinlove
|- proto.rb // CUIãã£ãããããã®ã¡ã¤ã³ãã¡ã¤ã«
|- unmo.rb // ãã£ããããããªãã¸ã§ã¯ãã®ã¢ãã«
|- responder.rb // å¿çãªãã¸ã§ã¯ãã®ã¢ãã«
|- dictionary.rb // è¾æ¸ãèªã¿è¾¼ã¿ç®¡çããã¯ã©ã¹
|- /dics // è¾æ¸ãã¡ã¤ã«ãæ ¼ç´ãããã£ã¬ã¯ããª
| |- random.txt // ã©ã³ãã ãªå¿çãè¿ãããã®è¾æ¸
| |- pattern.txt // ãã¿ã¼ã³ã«åã£ãå¿çãè¿ãããã®è¾æ¸
|- noby.rb // Webã¢ããªã®ã¡ã¤ã³ãã¡ã¤ã«
|- /views // ãã¥ã¼ã®ãã³ãã¬ã¼ããé
ç½®ãããã£ã¬ã¯ããª
| |- index.erb // ãã£ããã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ã表示ãããã¥ã¼
|- /public // éçãã¡ã¤ã«ãé
ç½®ãããã£ã¬ã¯ããª
|- nobycanvas.js // ãã£ã©ã¯ã¿ã¼ã®ç»åãã¢ãã¡ã¼ã·ã§ã³ãããJavascript
|- styles.css // ãã£ããã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ãã¬ã¤ã¢ã¦ãããcss
|- /img // ç»åãã¡ã¤ã«ãæ ¼ç´ãããã£ã¬ã¯ããª
|- /normal // 平常æã®ç»åãæ ¼ç´ãããã£ã¬ã¯ããª
|- /blink // ç¬ãã®ç»åãæ ¼ç´ãããã£ã¬ã¯ããª
|- /lookaround // å¨å²ãè¦åãç»åãæ ¼ç´ãããã£ã¬ã¯ããª
|- /talk // åãç»åãæ ¼ç´ãããã£ã¬ã¯ããª
~ 以ä¸ã«è¡¨æ
ãã¨ã®ç»åãæ ¼ç´ãããã£ã¬ã¯ããªãé
ç½®
ã½ã¼ã¹ã³ã¼ã
noby.rb
ã¯ã追å ãããã«ãã¼ã¡ã½ããchange_looks
ã«ãã£ã¦ãææ
å¤noby.mood
ã«æ²¿ã£ã表æ
ã®æ
å ±ããã¥ã¼ã«éãã¾ãã
ååã®è¨äºã¾ã§ã¯ããã«ãã¼ã¡ã½ããå
ã§ãã£ããããããªãã¸ã§ã¯ãnoby
ãçæãã¦ãã¾ãããã ãã«ãã¼ã¡ã½ããå
ã§çæããã¤ã³ã¹ã¿ã³ã¹å¤æ°ã¯ãªã¯ã¨ã¹ãã®åº¦ã«çæãããããããææ
å¤ã®ãããªå¢æ¸ããå¤ã®æ
å ±ãä¿æã§ããªããããªã®ã§ãã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ã§ã®çæã«ä¿®æ£ãã¾ããã
nobycanvas.js
ã§ã¯ããã¥ã¼ã®dataå±æ§
çµç±ã§åå¾ãã表æ
ã®æ
å ±ããã¨ã«ãã¢ãã¡ã¼ã·ã§ã³ãä½æãã¾ãã
ç»åã®éçã«ããããµã³ãã«ããã°ã©ã ãããã¢ãã¡ã¼ã·ã§ã³ã®ç¨®é¡ã¯å°ãªããªã£ã¦ãã¾ãã
noby.rb
require 'sinatra' require 'sinatra/reloader' require_relative 'unmo' # ä¼è©±ãã°ãæ ¼ç´ããé å log_area = [] # èµ·åæã«ãªãã·ã§ã³ãè¨å®ãã # ç¶æ ãä¿æãããªãã¸ã§ã¯ãã®çæã«ä½¿ç¨ configure do # ããã£çæ set :noby, Unmo.new('noby') end # ãã«ãã¼ã¡ã½ãããå®ç¾©ãã # ã«ã¼ãã£ã³ã°ã¡ã½ããã®ä¸ã§ä½¿ã helpers do def noby # ããã£ã¸ã¢ã¯ã»ã¹ noby = settings.noby end def prompt(resp_opt) # å¿çã表示ããéã®ããã³ãããä½æ resp_opt ? "#{noby.name}ï¼#{noby.responder_name}" : "#{noby.name}" end def change_looks # ææ å¤ã§è¡¨æ ãå¤åããã case noby.mood when -5..5 then 'talk' when -10..-5 then 'angry_talk' when -15..-10 then 'more_angry_talk' when 5..10 then 'happy_talk' when 10..15 then 'more_happy_talk' end end end # URL'/'ã«ã¢ã¯ã»ã¹ get '/' do # ä¼è©±ãã°ãåæåãã¦nobyfomã表示 log_area = [] erb :index end # URL'/'ã«POSTã¡ã½ããã§ã¢ã¯ã»ã¹ post '/' do # ã¦ã¼ã¶ã®å ¥åãåå¾ talk_text = params['inputarea'] # Responderã表示ãããã§ãã¯ããã¯ã¹ã®ç¶æ ãåå¾ # ãã§ãã¯ããã¦ãå ´åã¯ç¶æ ãç¶æ resp_opt = params['respoption'] @check = "checked" if resp_opt # ã¦ã¼ã¶ã®å ¥åãããã°å¿çãã¦ä¼è©±ãã°ã«è¡¨ç¤º unless talk_text.empty? @responder_resp = noby.dialogue(talk_text) log_area << "> #{talk_text}<br>" log_area << "#{prompt(resp_opt)}> #{@responder_resp}<br>" @noby_state = change_looks end @talk_log = log_area.join erb :index end
public/nobycanvas.js
document.addEventListener('DOMContentLoaded', function(){ /* é åã®è¦ç´ çªå· */ var index = 0; /* ãã£ã©ã¯ã¿ã¼ã®æ ç·ç¶æ ãç¢ºèª */ var nobyState = document.getElementById("nobycanvas").dataset.nobystate; /* åãç»åãæ ç·ãã¨ã«æ ¼ç´ */ var talkPtn = { talk: [ "img/normal/0000.png", "img/talk/0000.png", "img/talk/0001.png", "img/talk/0000.png", "img/talk/0001.png", "img/normal/0000.png" ], happy_talk: [ "img/happy/0000.png", "img/happy_talk/0000.png", "img/happy_talk/0001.png", "img/happy_talk/0000.png", "img/happy_talk/0001.png", "img/happy/0000.png" ], more_happy_talk: [ "img/more_happy/0000.png", "img/more_happy_talk/0000.png", "img/more_happy_talk/0001.png", "img/more_happy_talk/0002.png", "img/more_happy_talk/0000.png", "img/more_happy_talk/0001.png", "img/more_happy_talk/0002.png", "img/more_happy/0000.png" ], angry_talk: [ "img/angry/0000.png", "img/angry_talk/0000.png", "img/angry_talk/0001.png", "img/angry_talk/0000.png", "img/angry_talk/0001.png", "img/angry/0000.png" ], more_angry_talk: [ "img/more_angry/0000.png", "img/more_angry_talk/0000.png", "img/more_angry_talk/0001.png", "img/more_angry_talk/0000.png", "img/more_angry_talk/0001.png", "img/more_angry/0000.png" ] }; /* æ ç·ãã¨ã®ã¢ãã¡ã¼ã·ã§ã³ã®ãã¿ã¼ã³ãä½æ */ /* é常æã®ãã¿ã¼ã³ */ var normalPtn = [ ["img/normal/0000.png"], [ "img/normal/0000.png", "img/blink/0000.png", "img/blink/0001.png", "img/normal/0000.png" ], [ "img/normal/0000.png", "img/lookaround/0000.png", "img/lookaround/0001.png", "img/lookaround/0002.png", "img/lookaround/0003.png", "img/lookaround/0004.png", "img/normal/0000.png" ] ]; /* æ©å«ãããæã®ãã¿ã¼ã³ */ var happyPtn = [ ["img/happy/0000.png"], [ "img/happy/0000.png", "img/happy_blink/0000.png", "img/happy_blink/0001.png", "img/happy/0000.png" ] ]; /* ä¸æ©å«ã®æã®ãã¿ã¼ã³ */ var moreHappyPtn = [ ["img/more_happy/0000.png"], [ "img/more_happy/0000.png", "img/more_happy_blink/0000.png", "img/more_happy_blink/0001.png", "img/more_happy/0000.png" ] ]; /* æ©å«ãæªãæã®ãã¿ã¼ã³ */ var angryPtn = [ ["img/angry/0000.png"], ]; /* æã£ã¦ããæã®ãã¿ã¼ã³ */ var moreAngryPtn = [ ["img/more_angry/0000.png"], ]; /* é¢æ°ã®ä¸ã§ç»åãæä½ããããã®å¤æ° */ var animePtn = []; var imgAry = []; var timeoutId; /* å¿çæã®ã¢ãã¡ã¼ã·ã§ã³ã表示 */ function respAnime(looks) { imgAry = talkPtn[looks]; nobyState = ''; flipAnime(); } /* ã¢ãã¡ã¼ã·ã§ã³ã®ãã¿ã¼ã³ããã©ã³ãã ã«é¸æ */ function selectAnime() { imgAry = animePtn[Math.floor(Math.random() * animePtn.length)]; } /* ç»åãé çªã«è¡¨ç¤ºãã¦ã¢ãã¡ã¼ã·ã§ã³ãä½æ */ function flipAnime(){ timeoutId = setTimeout(flipAnime, 100); document.getElementById("nobycanvas").getElementsByTagName("img")[0].src = imgAry[index]; index++; if (index >= imgAry.length){ index = 0; clearTimeout(timeoutId); } } /* æ ç·ç¶æ ã«ãã£ã¦è¡¨æ ãå¤åããã */ /* å¿çæã¯åãã¢ãã¡ã¼ã·ã§ã³ã表示 */ switch (nobyState) { case 'talk': respAnime('talk'); animePtn = normalPtn; break; case 'happy_talk': respAnime('happy_talk'); animePtn = happyPtn; break; case 'more_happy_talk': respAnime('more_happy_talk'); animePtn = moreHappyPtn; break; case 'angry_talk': respAnime('angry_talk'); animePtn = angryPtn; break; case 'more_angry_talk': respAnime('more_angry_talk'); animePtn = moreAngryPtn; break; default: animePtn = normalPtn; break; } /* å¾ æ©æã¯é©å½ãªã¢ãã¡ã¼ã·ã§ã³ãé¸ãã§è¡¨ç¤ºãã */ setInterval(selectAnime, 5000); setInterval(flipAnime, 5000); });
ãã®ã³ã¼ãã®ã³ãããã«ã¯ã[chapter6-6]ã®ã¿ã°ãä»ãã¦ã¾ãã
å®è¡çµæ
ã¿ã¼ããã«ã§noby.rb
ãåããããã©ã¦ã¶ã«http://localhost:4567
ãå
¥åãã¾ãã
~/programinlove
$ruby noby.rb
ãã ã¦ãã¨ããããç¬é¡ã«ãªãã¾ãã
åèæ¸ç±
åèè¨äº
Sinatraã«ã¤ãã¦ã¯ããã¡ãã®è¨äºãåèã«ããã¦ããã ãã¾ããã
- Rubyの入門や書き捨てアプリを作る場合は sinatraがオススメ! - むかぁ~ どっと こむ
- SinatraとjQueryでおよそ100行で作るAjax掲示板アプリケーション - gaaamiiのブログ
- Sinatra: README (Japanese)
é¢é£è¨äº
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.0ï¼»ã¯ããã«ï¼½
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.1ï¼»CHAPTER3 ã»ãã¨ã«ç¡è½ï¼½
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.2ï¼»CHAPTER4 ããããã®GUIï¼½â
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.3ï¼»CHAPTER4 ããããã®GUIï¼½â¡
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.4ï¼»CHAPTER4 ããããã®GUIï¼½â¢
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.5ï¼»CHAPTER5 è¾æ¸ãçæã«ï¼½
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.6ï¼»CHAPTER6 ææ
ã³ã³ããã¼ã«ã®éè¡å¸«ï¼½â
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.8ï¼»CHAPTER7 å¦ç¿ã®ã¹ã¹ã¡ï¼½â
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.9ï¼»CHAPTER7 å¦ç¿ã®ã¹ã¹ã¡ï¼½â¡
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.10ï¼»CHAPTER7 å¦ç¿ã®ã¹ã¹ã¡ï¼½â¢
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.11ï¼»CHAPTER8 æç« ãä½ãåºãï¼½
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.12ï¼»CHAPTER9 ããã£ããããã¯ã¼ã¯ã«ã¤ãªããï¼½
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.13ï¼»ãããã«ï¼½