Sinatraで数字当てゲームを作った
・Railsチュートリアルを終えて
前のブログに書いたかもしれないが、ついこの間まではRuby on Railsチュートリアルをやっていた。
先日最後まで終えることができ、ツイッターのクローンサイトも一応完成はした。
一応・・・というのは、結局自分で考えて作ったものとは言えないから。 最後の章あたりはレベルが高すぎて正直何を言っているのか、 なんとなくでしか分からなかった。
機能拡張もしたかったが、明らかにレベルに合っていないので、一旦これで終了。 (この教材で学んだこと、疑問点などはそのうち別記事にしたい)
とはいえサーバーサイドの言語はRuby中心に勉強していこうとは思っているし、 何らかのアプリを作るならフレームワーク自体は使っていきたい。 当然Railsでもいいわけだが、ネットで検索していると 「初心者にはおすすめしない」という記事もある。
記事そのものもコメント欄での応酬も読ませて頂いた。
ガチ初心者としては、 「で結局どうしたら?」という感じではあるが、一通りRailsの機能を見た感じ、 やはり高機能すぎるというのは言えていると思う。 そのせいでめちゃくちゃ覚えることが多い。
もう少し、自分の把握できる範囲で使えるほうがレベルアップはしやすいのではないか。 例えるなら、今のRailsは攻撃力がめっちゃ高いが重量が重すぎて装備できないバトルアックスのようなもの。
それを無理やり使うよりは、攻撃力は劣るものの、 自分の力で振り回せる短剣を使ったほうが戦える。
というわけで、やや軽量級のSinatraを使ってみることにした。
・Sinatraを使ってみる
参考にした教材はこちら。 Webguesserというゲームを作る課題です。
必要なファイル等々を作ってから本編へ。
①1〜100までの間でランダムに数を生成
②ブラウザのフォームからユーザーが数字を入力
③ランダム生成の数とユーザーの入れた数字を比較し、メッセージを表示
大筋はこういうゲーム(最後の拡張はまだやってない)。
恥ずかしい話、これだけでも相当苦戦した・・・
・ルーティングハンドラが読めなかった
おなじみのHello Worldをブラウザに表示させるブロック。
まずこれの意味すら分からなかった(Railsにはget '/'なんてなかった!)。
require 'sinatra' get '/' do 'Hello world!' end
get
の部分がHTTPリクエストになっていて、例えばpost
にも出来る。
'/'
の部分はURLになっていて、この場合はルートURL。
「GETリクエストでルートURLにアクセスした時」という意味。
・変数のスコープが分からなかった
これはそもそもRubyの基礎がおろそかなのでは?という話だが、変数を定義してエラーが連発した。
get '/' do guess = params['guess'].to_i message = check_guess(guess) erb :index, :locals => { :random_number => rand_number, :message => message } end rand_number = rand(101) def check_guess(guess) if guess > rand_number "foobar" else "error" end end
これでif guess > rand_number
がエラーになるとか。ローカル変数だからアクセスできないのか?
と思って全部ルーティングのブロックに入れてもnilでエラー。
ネットで検索して何となく@をつけてインスタンス変数にしてみたりもしたが、変わらず。 何で使えないんだと思ったらこの記事にたどり着いた。
インスタンス変数は初期化しないといけないし、インスタンスメソッドでしかアクセスできない。 だから単純に@をつけただけではnilになってエラーになる。
何となくの知識しかなかったために、@をつければどこからでも使える変数になるのかと思っていた。
結局、この場は$rand_number
という形でグローバル変数を使うことで解決した。
初歩知識の一つだと思うが、全然知らなかった。基礎のなさを痛感。 他にも、paramsの取得方法や利用方法もまだまだわかっていない。
ブラウザにGETでアクセスしてページを表示するなら、 ブラウザ「から」情報を送信するにはPOSTを使うのかな? と思った。実際そういうふうにも出来るようだが、 今回はpostを使わずに済んでいる。
例えばデータベースに入力された情報を保存するとか、 その情報を他のページに表示させるとかいう場合は postなのだろうか。これは頭にとめておいて、今後はっきりさせていく。