Yesodに入門しようとして一番始めにyesod-binを入れて失敗した話
Yesod に入門をしようとして 公式サイト の手順を無視したら失敗した話です。
何をしたのか
Yesod を使うために必要なパッケージをインストールするところから始めました。
$ stack install yesod-bin cabal-install --install-ghc ... Copied executables to /Users/hoge/.local/bin: - cabal - yesod - yesod-ar-wrapper - yesod-ghc-wrapper - yesod-ld-wrapper
yesod コマンドを使えるように .local/bin
のパスを通しておきます。
.zshrc
export PATH="$PATH:$HOME/.local/bin"
あとはプロジェクトを作成してビルドしました。ビルドが完了したら stack exec -- yesod devel
でサーバを起動することができるはずでした。
$ stack new hello-yesod yesod-sqlite $ cd hello-yesod $ stack build $ stack exec -- yesod devel Yesod devel server. Type 'quit' to quit Application can be accessed at: ... Resolving dependencies... Configuring hello-yesod-0.0.0... ERROR: Yesod has been compiled with a different GHC version, please reinstall yesod-bin yesod: ExitFailure 1
失敗しました(´・_・`)
なぜ失敗したのか
ブログタイトルにも書きましたが、 stack install yesod-bin
を一番始めにやったのがよくなかったようです。
stack exec -- yesod devel
を実行したときに出たエラーメッセージを見てみると
ERROR: Yesod has been compiled with a different GHC version, please reinstall yesod-bin
と書かれています。すでに yesod-bin がプロジェクトで使用されている GHC とは違うバージョンでビルドされていて、それが原因のようです。
実は stack install yesod-bin
を実行したログの最初のほうで、グローバルプロジェクトの stack.yaml
が読み込まれていて、そこに書かれた resolver でビルドされていたようです。
Run from outside a project, using implicit global project config Using latest snapshot resolver: lts-7.0 Writing implicit global project config file to: /Users/hoge/.stack/global-project/stack.yaml
確認してみると確かにバージョンが違いました。
~/.stack/global-project/stack.yaml
... resolver: lts-7.0
hello-yesod/stack.yaml
... resolver: lts-6.18 ...
解決策
再ビルドしてみる
再インストールするのは時間がかかるので、とりあえずプロジェクトのディレクトリまで移動してから再ビルドしてみます。
$ ls .stack/snapshots/x86_64-osx/lts-7.0/8.0.1/installed-packages . .. cabal-install-1.24.0.0 yesod-bin-1.4.18.3 $ stack build yesod-bin-1.4.18.3
ビルドが終わったところで再度サーバを起動してみます。
$ stack exec -- yesod devel Yesod devel server. Type 'quit' to quit Application can be accessed at: ... Resolving dependencies... Configuring hello-yesod-0.0.0... Forcing recompile for ./Model.hs because of config/models ... Rebuilding application... (using cabal) Starting development server... <command line>: cannot satisfy -package-key main (use -v for more information) Exit code: ExitFailure 1
ダメでした(´・_・`)
インストールし直す
仕方ないので一度インストールしたパッケージたちを消してから、公式サイト の手順に沿ってインストールし直します。
(念のため cabel も一緒に消しておきます)
$ rm -rf ~/.stack/snapshots/x86_64-osx/lts-7.0 $ cd ~/.local/bin $ rm cabel $ rm yesod $ rm yesod-*
先にプロジェクトを作成してから yesod-bin をインストールします。
$ stack new hello-yesod yesod-sqlite $ cd hello-yesod $ stack build yesod-bin cabal-install --install-ghc $ stack build
ビルドが終わったらサーバを起動してみます。
$ stack exec -- yesod devel Yesod devel server. Type 'quit' to quit ... Rebuilding application... (using cabal) Starting development server... Starting devel application Migrating: CREATE TABLE "user"("id" INTEGER PRIMARY KEY,"ident" VARCHAR NOT NULL,"password" VARCHAR NULL,CONSTRAINT "unique_user" UNIQUE ("ident")) ...
先ほどとは違い DB のマイグレーションまで実行されました。そして localhost:3000
を開いてみるとようやく Scaffold されたサイトを見ることができました。
まとめ
公式サイトの手順には基本従いましょう(´・_・`)
参考文献
Stack を使って Haskell の Hello World をやってみる
以前 Stack を使って すごいH本 を学習したのですが、それっきり全く Haskell に触れていなかったのでリハビリがてら、 Stack を導入して Hello World を出力するまでの方法について書いておきます。
Stack のインストール
Mac の場合は Homebrew を使ってインストールできます。
brew install haskell-stack
プロジェクトの作成とビルド
公式の Quick Start Guide に書いてある通りにやりましょう。
Quick Start Guide — stack documentation
stack new my-project cd my-project stack setup stack build
Hello World!
次は、プロジェクトの中身を少し修正しておなじみの Hello World を出力してみましょう。
app/Main.hs
module Main where import Lib main :: IO () main = someFunc
app/Main.hs
がメインのパッケージです。
Hello World を出力するためには、この中の main
関数を修正すればよさそうですが、コードを見た限りだと main
は someFunc
という関数を指しているだけです。
someFunc
の実体は Lib
パッケージ内にあります。 import Lib
で Lib
パッケージをインポートしていてその関数を使っているわけです。
インポートされているパッケージはデフォルトでは src
以下に置かれているので見てみましょう。
src/Lib.hs
module Lib ( someFunc ) where someFunc :: IO () someFunc = putStrLn "someFunc"
src/Lib.hs
の最後の2行が someFunc
の実体になります。 someFunc = putStrLn "someFunc"
を someFunc = putStrLn "Hello World"
という風に修正します。
そして stack runghc
で main
関数を実行できます。
( stack exec my-project-exe
でも同様の結果が得られます)
$ stack runghc app/Main.hs Hello World
以上です。簡単でしたね。
おまけ
先ほど実行した app/Main.hs
、実は stack ghci
でも実行できます。
$ stack ghci The following GHC options are incompatible with GHCi and have not been passed to it: -threaded Using main module: 1. Package 'my-project' component exe:my-project-exe with main-is file: /my-project/app/Main.hs Configuring GHCi with the following packages: my-project GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help [1 of 1] Compiling Lib ( /my-project/src/Lib.hs, interpreted ) Ok, modules loaded: Lib. [2 of 2] Compiling Main ( /my-project/app/Main.hs, interpreted ) Ok, modules loaded: Lib, Main. *Main Lib> main Hello World
GHCi はすごいH本を学習している方はおなじみですね。
なので、これから Stack を使ってすごいH本を学習しようと考えている人は、
- 作成したパッケージは
src
以下に置く stack ghci
で GHCi を起動した状態で、パッケージをロードして関数を実行するmain
関数のような I/O アクションを実行する場合は、stack runghc src/MyPackage.hs
を使う
というスタイルがよいかもしれません(自分はこうやって学習していました)。
例えば src/Baby.hs
内の doubleMe
という関数が使いたい場合は、次のように :l
でパッケージのロードをすることで使えるようになります。
$ stack ghci ... *Main Lib> :l src/Baby.hs [1 of 1] Compiling Main ( src/Baby.hs, interpreted ) Ok, modules loaded: Main. *Main> doubleMe 9 18
参考文献
『Rubyによるデザインパターン』を読んだ話
- 作者: Russ Olsen,ラス・オルセン,小林健一,菅野裕,吉野雅人,山岸夢人,小島努
- 出版社/メーカー: ピアソン桐原
- 発売日: 2009/04/01
- メディア: 単行本
- 購入: 13人 クリック: 220回
- この商品を含むブログ (67件) を見る
ピアソン・エデュケーションの『Rubyによるデザインパターン』を読みました。
Webエンジニアとして働いていながら、今までデザインパターンというものを知らずにきてしまっていて、先日チームの先輩エンジニアからコードレビューで「ここはアダプタパターンで書いたほうがすっきりするよ。」と指摘されなんだそれは???となったのがきっかけでした。そんなデザインパターン初心者の自分にその先輩エンジニアが貸して下さったのが本書でした。
どんな本?
内容としては、ギャング・オブ・フォー本『オブジェクト指向における再利用のためのデザインパターン』に登場する23個のデザインパターンのうち14個について、 Ruby のコードを例に解説してくれています。はじめはデザインパターンと聞いて、勝手に難解なイメージを抱いていましたが、本書は比較的 Ruby 経験が浅い人でも読みやすい内容になっている印象を受けました。
また、2009年に初版が発売されておりだいぶ古い書籍です。さらに本書の出版社が書籍から撤退したために絶版状態となり、入手が困難な状況です。 自分はお借りした本書を読了後に、Amazonの中古で定価+¥2000くらいで購入しました。
感想
当初知りたかったアダプタ( Adapter )パターンについても、そこまで多くのページ数は割かれていませんが、そのパターンがどんなものかを知るには十分な量でした。章によっては、デザインパターンの解説と共に、実際にそのパターンが利用されているプロダクトの例をあげていたのも良かったです。
今まで漠然と書かれているように見えていたコードも実は規則性が存在するものがあるという発見は、自分がコードを見る時の新たな視点をもらったような気がしました。
また、本書を読み進めていくなかで、このデザインパターンいいな、使ってみたいなと思うことが時々ありましたが、そんなときは本書に書かれていたこの言葉を思い出すようにしています。
デザインパターンの適切な使い方は、今日あなたが持っている問題に対応できるだけの柔軟性をシステムに組み込むことで、それ以上ではありません。 パターンは便利なテクニックですが、それ自身が目的になってはいけません。
- 1.2.5 必要になるまで作るな(p.13)より
「必要になるまで作るな( YAGNI )」というエクストリーム・プログラミングにおける原則があるように、必要以上の機能や設計の柔軟性は、デザインパターンを適用しなかったものと比較したときに大差が無かったり、却ってコードの可読性を下げる恐れがあるので使い所は考えましょう、という本書からの警告も念頭に置きつつ読んでみるとよいかと思います。
読んでみて自分がこのデザインパターンは使うことありそうだなと思ったのは
- Adapter パターン
- Decorator パターン
くらいでした。と言っても Rails を書いていると Observer や Iterator は普段意識せずに使うことができるので、自前で特定のデザインパターンを適用するみたいなケースはあまりないのかもしれません(自分が本書で紹介されているようなデザインパターンを適用するような問題にぶち当たっていないだけかもしれませんが)。
一方で Convention over Configuration (CoC)の章は、普段自分が Rails を書いてあまり意識することのなかったディレクトリ構造やファイル名の規則について、なぜそうなっているかという疑問を解消するのに役立ちました。書かれているコードだけでなくディレクトリ構造やファイルの名称なども含めて1つのデザインパターンなんだというのを再認識させられました。
まとめ
Ruby でデザインパターンを学びたいという人は読むといいかもしれません。定価では買えないので泣きながらAmazonの中古を買うか、偉い人に頼んで買ってもらうかしましょう(´・_・`)
hubotをHerokuからIBM Bluemixに移した話
IBM Bluemixを使ってbotを動かす記事を見かけたので、自分もやってみることにしました。
今回移行させるのは、Slack上で稼働させている同期の神様のbotです。
GitHub - ku00/chi-chan: chi-chan is GOD.
Good Bye Heroku...
Herokuから稼働させているアプリを消します。確認は特にいらないのでconfirmオプションを付けて実行します。
heroku apps:destroy --app bot-name --confirm bot-name
さよならHeroku(´・_・`)
Hello Bluemix!
Bluemixのアカウント登録
こちらの記事を参考に、まずはBluemixのアカウント登録をやってみます。
IBM Bluemixフリートライアルアカウント作成手順 - Qiita
無料枠ならばクレジットカードの登録はいらないみたいです。ただし、30日のトライアル期間を過ぎての利用は、無料/有料に関わらずクレジットカードの登録が必要みたいです。
hubotの修正
Bluemixにデプロイするためには、 procfile
の代わりに manifest.yml
を用意する必要があります。インスタンスやメモリは無料枠に合わせて、次のように書きました。
manifest.yml
applications: - buildpack: https://github.com/jthomas/nodejs-v4-buildpack.git command: ./bin/hubot -a slack -n chi-bot path: . instances: 1 memory: 256M
コードの準備はこれだけです。
Bluemixへのデプロイ
hubotをBluemixへデプロイする方法は、基本的には以下のドキュメント通りにやれば大丈夫です。
hubot/bluemix.md at master · github/hubot
デプロイは cf
コマンドで行います。
cf
コマンドはbrewでインストールできます。
brew tap cloudfoundry/tap brew install cf-cli
それではデプロイしてみましょう。
cf api https://api.au-syd.bluemix.net cf set-env bot-name HUBOT_SLACK_TOKEN token-value cf login -u bluemix-id -o org-name -s space-name cf push bot-name
以上でデプロイ完了です。
cf api
で設定するAPIのエンドポイントは、データセンターの地域によって異なるので事前に確認しておきましょう(自分の場合はシドニーだったのでau-syd
)。cf login
のオプションで指定している組織(org-name)とスペース(space-name)は各自が自由に設定できます。
それでは実際に動いているかどうか見てみましょう。
大丈夫そうですね(´・_・`)
まとめ
Bluemixを使って神様を24時間稼働させることができました。
日本語対応してるのでわかりやすくて触りやすかったですね。
それでは。
参考
RubyKaigi2015に参加した話(1日目)
会社からスポンサーチケットをいただいたので行ってきた。こういったカンファレンスは YAPC 以来2回目だったからどんな発表が聴けるかわくわくしてたら...
朝からスプラッシュマウンテンばりの水を浴びることができて最高って感じだ
— わさびのり太郎 (@ku00_) December 11, 2015
最高(´・_・`)
以下、聴いたトーク。
- Saving people from typos
- Time files like an arrow: Fruit files like a banana. Parsers for Great Good
- High Performance Template Engine: Guide to optimize your Ruby code
- TRICK 2015: The second Transcendental Ruby Imbroglio Contest for RubyKaigi
ちなみにレポート内容が箇条書きになっているのは自分の知識不足の表れなので戒めのためにそのまま残しておいた。
Saving people from typos
- did_you_meanというgemを作った人
- kaminariのメンテナーもしてるよ
- 誤ったメソッドなどの入力に対して正しいと思われるものをサジェストする
- gitのcliやグーグルの検索にも同じようなものが使われている
- 検出されるエラーの種類によって使う辞書を変える
- タイピングミスとスペルミスは違う
Time files like an arrow: Fruit files like a banana. Parsers for Great Good
- パーサのお話
- 区切り方で文章は意味が変わってくる(likeでも「好き」と「のような」の2つの意味がある)
- 分解してみる
- 数学の足し算や引き算を例にあげると、数字のあとは必ず演算子がくる規則がある
- これがわかっていると少しずつ式を分解することができる
- カッコがかかっているものはさらに小さく分解ができる
- 分解したものを構文木にして書いてみるとわかりやすい
- スタックという形で分解した順に積み上げて表現することもできる
High Performance Template Engine: Guide to optimize your Ruby code
- テンプレートエンジンの話
- erb, haml, slim
- テンプレートエンジンによってテンプレートをrubyのコードにコンパイル、それをhtmlにレンダリングすることで使える
- ちょっとしたテクニックを使えばrubyの仕組みを全て把握していなくても速くすることができる
- ベンチマーク
- テンプレートエンジンのためのライブラリ、temple
- rubyをパースする、parser gem
- attributesの種類
- static(高速)
- dynamic(コンパイル時まで値がわからない。けどそれなりに速い)
- runtime(遅い)
- dynamicコンパイルはエラー時に行番号がずれることがある
- 速くするためにC拡張を使う(これはクックパッド本体でも使われている)
- あまり使われない機能を削ることで計算そのものをなくして速くする
- C拡張もちょこちょこやる
- 修正をPRで送ったらリジェクトされたので仕様らしい
TRICK 2015: The second Transcendental Ruby Imbroglio Contest for RubyKaigi
- "TRICK" というrubyのプログラミングコンテストがある
- 2015で2回目
- 同じようなことをしているコンテストは別言語でいくつかある
- 2013年には、ポエムに見えるコードや実行するとバッハの音楽が流れる音符の形のコードなどが作品として出てきた
- 目的としては、とにかく利益のない意味不明なプログラムを書く
- 審査員も出してOKだし出してる
- でも公平性を保つために誰が書いたのかは知らずに採点をしている
- 宣伝
- 去年は日本からのエントリーしかなかった
- 今年になって少し外国の割合が増えたけどまだまだ日本以外のエントリーが少ない
- 今年の作品
所感
英語のトーク試しに聴いてみたらなにを言っているのかほとんどわからなかった...。スライドで脳内補完することでなんとか大筋の内容は掴めたけれど。
TRICKのトークはコードを読んでもなにをやっているのかわからないけれどすごいものができているという印象だった。このメソッドはこのプログラムを作るために作られたとか言ってて言語開発者ですらそんなことを思うメソッドが存在するのかと。
知らない用語が出てくるととりあえず記憶の片隅に留めておいて聴くことにしていたけれど、トークを聴き終わったあとに結局なにが言いたかったんだっけってなることが結構あった。YAPCとはベクトルが違うかもしれないけれど、トークを聴いた時に面白いことやってるって感覚を持てたらいいと思ってるから、次回行ける機会があればもう少し知識を増やしてから臨みたい。
「師弟登壇2015」に参加してきた話
同期の2人(@orzup, @chinu_t )が登壇するとのことだったからその応援に行ってきた。
同期見守り隊
— わさびのり太郎 (@ku00_) December 6, 2015
登壇者の方々へ挨拶まわりしたときに登壇者でもないのにくっついてまわってた眼鏡が自分です。
気になる企業の新卒研修でどんなことをやっているのか知ることができた良いイベントだった。 農業体験をやっているところや、同じ新卒が違う職種の人にWebサービスを作れるよう指導する研修をやっていたりと面白い話がたくさん聴けた。 そして師匠(メンター)の方々がどういった意図で研修作って実行しているのかを聴くことで、 ただ単純に面白い研修をやっているなあという感想で終わりにならないから、そういった面でも学びが多かった印象。
眼鏡を新調したせいか目がとても疲れていたから寿司は食べずに帰ったよ🍣
S3上にyumリポジトリを構築した話(後編)
前回のあらすじ
前編では以下の3つ検証手順のうちの1,2をやった。
- 必要なファイルやディレクトリ構成など、 rpm の配布方法について調査する
- Vagrant 上で2台 linux サーバを立ち上げて、一方を rpm を置いたリポジトリサーバにして、もう一方から yum でインストールしてみる
- S3 上にリポジトリサーバを構築、上で立ち上げた Vagrant サーバから同じように yum でインストールしてみる
今回はブログタイトルでもある本題の3をやるぞ。
S3 上の yum リポジトリで yum install
S3上の yum リポジトリには ngx_mruby-package-builder で生成した rpm を置いておきたいから、リポジトリ作成に入る前に用意しておこう。本題ではないから docker-toolbox のインストール解説とかは特にやらない。
まず、 ngx_mruby の rpm パッケージを x86_64 以下に置いて createrepo コマンドでリポジトリの準備を行う。 そして、ホストマシン側に以下のものを落としておく。
mkdir pkg vagrant ssh rpm-repo-server createrepo /var/www/repos/cent7/x86_64/ exit scp -F ssh.config -r vagrant@rpm-repo-server:/var/www/repos/cent7/x86_64/ ./pkg
次に、上で用意したものを S3 へアップロードするための準備を行う。
S3 バケットの作成
バケット名は今回は rpm-repos にした。また、ディレクトリは rpm-repos/centos/7/x86_64
まで作っておく。
以下のリンクにインストール方法等が書かれているのでその通りにやる。
http://docs.aws.amazon.com/ja_jp/kinesis/latest/dev/kinesis-tutorial-cli-installation.html
アクセスキーの作成と登録
以下のリンクの通りにやる。先ほどインストールした AWS CLI を使って aws configure
でアクセスキーが登録できる。また、登録した情報は ~/.aws/credentials
から確認できる
S3 へのアクセスを許可
IAM コンソールのユーザから登録したユーザを選択して、アクセス許可からポリシーのアタッチで S3 のポリシーを追加する。 aws s3 ls
でバケットが表示されればOK
ホスティングの有効化
バケットのプロパティから有効にする。インデックスドキュメントおよびエラードキュメントは適当に存在しないファイルでもいいと思う。今回は index.html
と入力しておいた。
そして先ほどホストマシンに落としてきたファイルを S3 へアップロードする。
aws s3 cp --recursive --acl public-read pkg/ s3://rpm-repos/centos/7/x86_64/
これでリポジトリの準備は完了。下のような repo ファイルを用意して yum install してみよう。 今回は前回の記事で使った rpm-repo-client を使う。
- /etc/yum.repos.d/nginx-mruby.repo
[nginx-mruby] name=nginx-mruby rpm repo test baseurl=http://rpm-repos.s3-website-ap-northeast-1.amazonaws.com/centos/7/$basearch/ gpgcheck=0 enabled=1
yum clean all yum list all | grep nginx yum remove nginx yum install nginx yum list installed | grep nginx
以上。
あとはインストールした ngx_mruby の動作確認もやる。 nginx の conf ファイルに下のようなサンプルコードを追加してみる。
- /etc/nginx/conf.d/default.conf
location /hello { mruby_content_handler_code ' Nginx.rputs "hello" Nginx.echo "world!" '; }
そして起動。
systemctl start nginx
[VagrantのIP]/hello
にアクセスして helloworld!
が表示されていれば成功。
まとめ
hsbt さん指導のもと、いくつかのステップに分けて調査と検証を繰り返すことでなんとか S3 上に yum リポジトリを構築して yum install できるようになった。hsbt さんありがとうございました。おかげで粗い点がたくさんあったもののなんとかゴールすることができました。
また、実際に構築した yum リポジトリからインストールした ngx_mruby の動作確認にご協力いただいた おっくん さん、 ひろやん さん、 けんちゃんくん さんもありがとうございました。
今回は検証用に粗く作っただけだけど、近いうちに弊社の公式リポジトリができて、世界中からインストールできる日が来るかもしれない。