<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
  <title>shimba.co</title>
  <link href="https://shimba.co" />
  <link rel="self" type="application/atom+xml" href="https://shimba.co/feed" />
  <updated>2024-04-28 00:00:00 UTC</updated>
  <author>
    <name>Shimba, Koji (@shimbaco)</name>
  </author>
  <id>tag:shimba.co</id>

  
    <entry>
      <title>Mewstのアバター画像がGravatarに対応しました</title>
      <link href="https://shimba.co/2024-04-28-mewst-gravatar" />
      <id>tag:2024-04-28-mewst-gravatar</id>
      <updated>2024-04-28 00:00:00 UTC</updated>
      <summary><p><img src="https://i.imgur.com/qHuoacg.jpg" alt="MewstのGravatar対応" /></p>
<p><a href="https://mewst.com/settings/profile">Mewstのプロフィール編集ページ</a>で設定できるアバター画像ですが、<a href="https://shimba.co/2024-04-27-mewst-beta">リリース当初</a>は外部サービスの画像URLを登録してもらう以外に設定する手段がありませんでした。
この外部サイトの画像URLを登録してもらうアイデアは<a href="https://nostr.com/">Nostr</a>から来ていて、潔さがすごいなと思って真似していました。</p>
<p>しかしやっぱりこの方法はわかりづらいですし、画像をどこに保存するか？という問題が出てきてしまいます。</p>
<p>そのため先ほど<a href="https://ja.gravatar.com/">Gravatar</a>というプロフィール管理サービスに保存されているアバター画像をMewstで使えるようにしました。
Gravatarに登録いただく必要はありますが、登録してそこにアバター画像をアップロードすれば、その画像をMewstのアバター画像にすることができます。</p>
<p>Gravatarのアバター画像を使うためにGravatarのメールアドレスの入力をお願いしています。
なぜMewstに登録したときのメールアドレスを使っていないかというと、今後1つのプロフィールを複数人で管理する機能を提供する予定があるためです。
1つのプロフィールに複数のアカウントが紐づくことになるため、Mewstに登録したときのメールアドレスをそのまま使うと「どのアカウントのメールアドレスを使うか？」という問題が出てきてしまいます。
そのためGravatarのメールアドレスを入力いただくようにしてMewstのアバター画像として使うGravatarアカウントを明確にしています。</p>
<p>アバター画像の登録が少し楽になったMewstをよろしくお願いします。</p>
</summary>
    </entry>
  
    <entry>
      <title>マイクロブログ「Mewst (ミュースト)」のベータ版をリリースしました</title>
      <link href="https://shimba.co/2024-04-27-mewst-beta" />
      <id>tag:2024-04-27-mewst-beta</id>
      <updated>2024-04-27 00:00:00 UTC</updated>
      <summary><img alt="" width="128" src="https://mewst.com/icon-192.png">
<p><a href="https://shimba.co/2023-01-18-introducing-mewst">Mewst (ミュースト) というマイクロブログサービスを作り始めている</a> という記事を公開してから1年以上が経ちました。その間も細々と開発は続いていましたが、途中まで作ったものを壊したりしていたらこんなに時間が経ってしまいました。</p>
<p>作ったり壊したりを繰り返していくうちにサービスの方針が明確になってきたので、一旦今できているものをベータ版という形で公開しようと思います。</p>
<p><a href="https://mewst.com">https://mewst.com</a></p>
<p>Mewstは160文字で今の気持ちや状況を記録できるマイクロブログです。緊張感なくほっとした気持ちで使えるサービスを目指しています。</p>
<p>具体的には以下のような特徴があります。</p>
<h2>タイムラインは時系列で表示されます</h2>
<p>おすすめのタイムラインなどはありません。</p>
<p>サービスが提供するアルゴリズムによって表示されるポストは魅力的なものもありますが、何が出てくるかわからない怖さみたいなものもあるかなと思っています。
Mewstは自分がフォローしている人のポストだけ表示されるので、どんなポストを表示するかを自分で制御することができます。</p>
<h2>ポストに直接反応する手段は「スタンプ」のみ</h2>
<p>メンションやリプライといった機能はありません。スタンプという他のサービスでいう「いいね」でのみ反応することができます。</p>
<img width="396" alt="スタンプされている様子" src="https://github.com/mewstcom/mewst/assets/56767/d3aa7834-5627-4e44-b3fc-ede887492db9">
<p>仲の良い人とは他のサービス上でも繋がっている (繋がる) と思いますし、直接やり取りしたいときはそちらのサービスで行うと良いかなと思っています。</p>
<p>開発当初はリプライ機能を追加していたんですが、まあ要らないかと思い消したところ見た目や実装もシンプルになりました。</p>
<p>「いいね」のような反応をスタンプと呼んでいるのは、悲しいポストなどにも押しやすくするためです。
「最近調子悪い…」みたいなポストに「いいね」されると、悪気がないことはわかっていてもちょっと微妙な気持ちになるので…。
「スタンプ」という表現には特に感情は含まれていないので、どんなポストに対しても「読んだよ」くらいの気持ちで押すことができ、押された側も「読まれたな」くらいの気持ちで受け取れます。</p>
<h2>スタンプ数などの数字は表示されません</h2>
<p>押されたスタンプの数を集計して表示するといったことはしていません。</p>
<p>どのポストが人気かといったことが定量的にはわからないので物足りなさはあるかもしれませんが、数字を見て一喜一憂するところから少し距離を置きたい人には居心地が良いかもしれません。</p>
<h2>フォロー/アンフォロー情報は公開されません</h2>
<p>ある人が誰をフォローしているのか・されているのかや、自分が誰にフォローされているのかといったことはわからないようになっています。
そのため他の人の目を気にせず気軽に好きな人だけフォローすることができます。</p>
<p>また、スタンプ数と同じようにフォロー数やフォロワー数も表示されません。
フォロワー数をドラゴンボールの戦闘力のように扱っているのは見ていて楽しい一方疲れることもあるので、表示しないようにしています。</p>
<h2>画像や動画をアップロードする機能がありません</h2>
<p>画像や動画はテキストと比べるとファイルサイズが大きいため、保管するのにはそれなりにお金がかかります。</p>
<p>Mewstは個人が運営しているサービスなので、サーバー費にかけられるお金はあまりありません。Mewstをなるべく長く運営するには出費をなるべく抑えることが大切なので、保管にお金がかかる画像や動画は扱わないことにしました。
アバター画像も画像のURLを保存してもらい、それを表示するだけにしています。
でもまあアバター画像くらいはアップロードできても良いかな…。</p>
<p>画像がアップロードできないのは初期のTwitterもそうでした。
(Twitterはアバター画像はアップロードできましたが)</p>
<p>Twitterに画像をアップロードできない間は<a href="https://ja.wikipedia.org/wiki/Twitpic">Twitpic</a>やInstagramなど画像に特化したサービスにアップロードし、そのURLをツイートしていました。
他のサービスを組み合わせるこのやり方は個人的に好きなので、Mewstでも同じようにできないかなと思っています。</p>
<p>Mewstにはポストカードを表示する機能があるので、画像を見せたいときは他の写真アプリなどに画像をアップロードしてURLをポストすることで実現できます。</p>
<img width="752" alt="Mewstに表示されたポストカードの様子" src="https://github.com/mewstcom/mewst/assets/56767/11350530-eb46-4363-a7ee-d2aea904a638">
<p>Mewstではこのように他のサービスとうまいこと連携して、コア機能はなるべく小さいまま色んなことができるサービスにしていきたいです。</p>
<p>うまいこと連携するための機能 (OAuthやWeb API) は今はまだありませんが、今後追加したいと思っています。</p>
<hr />
<p>既存のサービスと比べるとできないことだらけで不便かもしれませんが、試していただけたら嬉しいです。</p>
<p><a href="https://mewst.com">https://mewst.com</a></p>
<p>僕のプロフィールページはこちらになります。</p>
<p><a href="https://mewst.com/@shimbaco">https://mewst.com/@shimbaco</a></p>
<p>Mewstに関することは以下のサービスで発信しています。
良かったらフォローなどお願いします。</p>
<ul>
<li><a href="https://mewst.com/@mewst">Mewst</a></li>
<li><a href="https://bsky.app/profile/mewst.com">Bluesky</a></li>
<li><a href="https://discord.gg/tNwVpJ4Jfk">Discord</a></li>
<li><a href="https://www.threads.net/@mewstcom">Threads</a></li>
</ul>
<p>また、ソースコードも公開して開発しています。
もし興味あればgit cloneなどお願いします。</p>
<p><a href="https://github.com/mewstcom/mewst">https://github.com/mewstcom/mewst</a></p>
<p>居心地の良いマイクロブログになりたいMewstをよろしくお願いします。</p>
</summary>
    </entry>
  
    <entry>
      <title>NuPhy Air75キーボードを使い始めた</title>
      <link href="https://shimba.co/2023-06-04-hello-nuphy-air75" />
      <id>tag:2023-06-04-hello-nuphy-air75</id>
      <updated>2023-06-04 00:00:00 UTC</updated>
      <summary><p><img src="https://i.imgur.com/comAyGV.jpg" alt="NuPhy Air75" /></p>
<p><a href="https://nuphy.com/collections/keyboards/products/air75">NuPhy Air75</a>というメカニカルキーボードを買って使い始めました。
とても良いです。</p>
<p>今まではAppleのTouch IDを使うためにMacBook Proのキーボードを使っていました。ただ去年Apple Watchを買って使い始めてからTouch ID相当のことがApple Watchでできるようになったので、Appleのキーボードを使い続ける必要もないのでは…？となっていました。Touch ID搭載のMagic Keyboard (ブラック) も全然出ないし…。</p>
<p>昔HHKBやRealforceを試した時期もあったんですが、Appleのキーボードのキー配置と結構違ったりしたのでいまいち馴染めませんでした。あとはAppleのキーボードのようにキーストロークが浅めのもののほうが打ちやすいというのもありました。</p>
<p>Appleのキーボードと同じ感じのキー配置でキーストロークが浅めのメカニカルキーボードがないかなあと漠然と思っていたところ、Rebuild.fmでnaoyaさんやhakさんがNuPhyのキーボードを買ったという話を聴きました。</p>
<ul>
<li><a href="https://rebuild.fm/357/">Rebuild: 357: Keyswitch Room (naoya)</a></li>
<li><a href="https://rebuild.fm/361/">Rebuild: 361: Quadruple Layer Baumkuchen (hak)</a></li>
</ul>
<p>へ〜と思いながら<a href="https://nuphy.com/collections/keyboards">NuPhyのページ</a>を見に行ったところ、Airシリーズの存在に気づきました。Rebuildの中でも言及されてたかもですが、 <code>ロープロファイルキーボード</code> というものの存在と意味をこのとき初めて認識しました。<br>
これは僕のためのキーボードでは…！？キー配置もAppleのキーボードに近いし、何より見た目がすごくかわいい…！ということで勢いでポチりました。注文してからもYouTubeでレビューやタイピング音を流す動画をいろいろ見て気を高めていました。</p>
<ul>
<li><a href="https://youtu.be/a2kdtLoCe2E">NuPhy Air75 Typing Sounds - Gateron Red / Blue / Brown</a></li>
</ul>
<p>キーボードは一週間弱で届きました。思ったよりも早く届いたのでありがたかったです。<br>
開封して触ったところとても良いです。キースイッチは茶軸にしました。適度な打鍵感があり音も心地良いです。そんなに深く打たなくても底打ちする感じがAppleのキーボードに慣れている身としてはとても良いです。</p>
<p>Appleのキーボードに比べてキーの位置が若干高そうな感じがしたので、キーボードと一緒に<a href="https://nuphy.com/collections/accessories/products/mono-wrist-rest?variant=40282519273581">Mono Wrist Rest</a>というパームレストも買いました。木目調で良い感じです。</p>
<p><a href="https://nuphy.com/collections/keycaps/products/twilight-nsa-dye-sub-pbt-keycaps">COAST Twilight nSA Dye-sub PBT Keycaps</a>というちょっと暗めのキーキャップも買ったので、そのときの気分によって入れ替えたりして遊ぼうかと思います。</p>
<p>今回はキースイッチは追加で買わなかったんですが、<a href="https://nuphy.com/collections/switches/products/nuphy-wisteria-t55-switches">NuPhy Wisteria</a>というNuPhy独自のキースイッチも良い音を出しそうで気になってます。これを買ったら本格的にキーボード沼に浸かりそうな気がしている…。しばらく茶軸を楽しんでから購入検討しようかと思います。</p>
</summary>
    </entry>
  
    <entry>
      <title>Mewstアップデート (2023-01-25)</title>
      <link href="https://shimba.co/2023-01-25-mewst-update" />
      <id>tag:2023-01-25-mewst-update</id>
      <updated>2023-01-25 00:00:00 UTC</updated>
      <summary><p><a href="https://shimba.co/2023-01-18-introducing-mewst">Mewstを公開してから一週間が経ちました</a>。
この間にちょこちょこと改善を続けてきたので記事にまとめておこうと思います。
今後も定期的に記事にまとめていきたいです。</p>
<h2>Twitterと連携してから一定時間経つとTwitterにクロスポイントできなくなる問題の修正</h2>
<p>これはOAuth認可したときに得たアクセストークンを使い続けた結果有効期限が切れて、TwitterのWeb APIにリクエストできなくなっていただけでした…。</p>
<p>期限が切れたらリフレッシュトークンで新しいアクセストークンを得るようにして、ずっとクロスポイントできるようになりました。</p>
<h2>Twitter連携したときにどのアカウントと連携したかを表示するようにした</h2>
<p>すごく細かい変更ですが、これによりどのアカウントと連携してるんだっけ？というのが無くなったので嬉しいです。</p>
<p><img src="https://user-images.githubusercontent.com/56767/214370972-9c883a42-77f6-4b47-afef-9c2010aa03d8.png" alt="Mewst 2023-01-25 02-56-02" /></p>
<h2>アバター画像がアップロードできるようになった</h2>
<p>公開当初から僕のアバター画像をサイト上に表示していましたが、実はあれは固定で表示しているだけで、最近まで画像アップロード機能を使ったものではありませんでした。
アップロード機能自体はありましたが、本番環境の設定が足りておらず画像がアップロードできない状態でした。</p>
<p>設定を追加して、今はアップロードできるようになっています。</p>
<h2>タイムラインとプロフィールページにページネーションを設けた</h2>
<p>投稿を続けていると無限に投稿が表示されてしまうため、ページネーションを設けました。</p>
<p>タイムラインは過去の投稿を振り返ることがあまりなさそうなのと負荷軽減的な目的で一定期間までの投稿しか見れないようにするかもしれないので、カーソル型のページネーション (この投稿以降の投稿を表示するといった方式) を実装しました。</p>
<p>カーソル型のページネーション:</p>
<p><img src="https://user-images.githubusercontent.com/56767/214372304-5588b5d6-17aa-49ab-817e-44820a4b7c2f.png" alt="image" /></p>
<p>プロフィールページには自分の投稿だけが表示され、自分の投稿は過去のもの含めて全て見たいので、全て見やすいようにオフセット型のページネーション (1ページ...nページみたいな方式) を実装しました。</p>
<p>オフセット型のページネーション:</p>
<p><img src="https://user-images.githubusercontent.com/56767/214373438-c584c52e-e4dc-44fc-acc0-51d23a8e126f.png" alt="image" /></p>
<p>ゆくゆくは<a href="https://twilog.org/">Twilog</a>や<a href="https://annict.com/@shimbaco/records">Annictの記録一覧ページ</a>みたいに月別に投稿が表示できるような機能を追加して、過去の自分の投稿が振り返りやすくしたいです。</p>
<h2>言語選択の文言を修正</h2>
<p>これも非常に細かい話ですが、言語選択のセレクトボックス内の文言を修正しました。</p>
<p><img src="https://user-images.githubusercontent.com/56767/214374127-2886314d-3819-44ae-8744-c7b94854d3ac.png" alt="スクリーンショット 2023-01-25 3 12 09" /></p>
<p>修正前は日本語でサイトを表示していたとき「英語」と「日本語」が表示されていましたが、これだと日本語がわからない人が日本語でサイトを表示したとき英語に戻すのが難しくなるため、↑のスクショのように英語を併記するようにしました。</p>
<h2>細かい見た目の調整</h2>
<p>横幅がページごとにマチマチだったりしたのでそのあたりを調整したり、ナビゲーションバーのロゴの大きさや色を調整するなどしました。</p>
<h2>その他リファクタリングなど</h2>
<p><a href="https://dev.37signals.com/vanilla-rails-is-plenty/">Vanilla Rails is plenty</a> (<a href="https://techracho.bpsinc.jp/hachi8833/2023_01_12/124378">翻訳</a>) などを参考に
サービスクラスを使わずに実装するように心がけたりしていましたが、大量のconcernsなモジュールの中にメソッドやコールバックなどを入れていくのも見通しが悪くなりそうだなとも思ったので、モジュールではなくクラスを定義してデリゲートするように修正するなどしていました。
これによりそのモデルでどんなことができるのかがメソッドレベルで把握しやすくなったような気がします。</p>
<hr />
<p>以上が直近のアップデート内容でした。</p>
<p>コツコツとアップデートを重ねるMewstをよろしくお願いします。</p>
<p><a href="https://www.mewst.com">https://www.mewst.com</a></p>
</summary>
    </entry>
  
    <entry>
      <title>Mewst (ミュースト) というマイクロブログサービスを作り始めている</title>
      <link href="https://shimba.co/2023-01-18-introducing-mewst" />
      <id>tag:2023-01-18-introducing-mewst</id>
      <updated>2023-01-18 00:00:00 UTC</updated>
      <summary><p>昨年末あたりからTwitterが音楽性の違いを見せ始めてきました。
このまま使い続けるのもなんかなあと思い始め、<a href="https://mastodon.social/@shimbaco">Mastodon</a>を使い始めるようになりました。</p>
<p>MastodonはTwitterには無い機能などもあって結構良いんですが、分散型という仕組みが機能を複雑にしているような気がしています。
具体的には誰かをフォローするときのステップ数が多いです。同じサーバの人をフォローするならTwitterと同じ感じでできますが、
別のサーバの人をフォローするときは一度その人のプロフィールURLをコピーし自分のサーバ上にペーストして、それでフォローボタンを押すといったステップを踏む必要があるはずです。
分散型という特性は面白いものだとは思いますが、個人的にはあまり興味が無いというのもあり、単に複雑なものを使っているという気持ちになります。</p>
<p>というような気持ちを去年の11月6日にツイートしたりしていました。</p>
<p><a href="https://twitter.com/shimbaco/status/1588925720587534336">https://twitter.com/shimbaco/status/1588925720587534336</a></p>
<blockquote>
<p>正直Mastodonの分散型としての側面にはあまり興味がなく、別のインスタンスの人をフォローするときに面倒みたいなところが少し気になる。つまりJaikuとかWassr復活してほしい🙏</p>
</blockquote>
<p>昔は<a href="https://ja.wikipedia.org/wiki/Jaiku">Jaiku</a>とか<a href="https://ja.wikipedia.org/wiki/Wassr">Wassr</a>とかがあって、Twitterが落ちたりしていたときは避難先として使っていました。
そこでも (僕がフォローしている範囲で) ちょっとしたコミュニティが形成されていて、Twitter落ちてるね〜みたいなやり取りをして楽しんでいました。
最近は僕の観測範囲が狭いこともあるかもしれないですが、そういったサービスが見当たらないです。いろんな人がオレオレTwitterを作ってくれないかなあと思っていました。</p>
<p><a href="https://twitter.com/shimbaco/status/1593503745530220544">https://twitter.com/shimbaco/status/1593503745530220544</a></p>
<blockquote>
<p>Twitterには穏やかに存続してほしいけど、オレオレTwitterみたいなのが乱立するところも見たいな</p>
</blockquote>
<p>思っていたんですが、他力本願なのもなんかなあという気持ちになり、自分で作るか！と思って作り始めました。</p>
<p>Mewst (ミュースト)<br>
<a href="https://www.mewst.com">https://www.mewst.com</a></p>
<p>まだ全然何もできないのでアルファ版という体裁で公開しています。現在は開発者である僕しかログインできないし投稿もできないです。
ログインすると一応フォロー機能やタイムラインは存在します。けどまだそのくらいしか機能が無いです。
自分が音楽性の違いに対してどう向き合おうとしているかを意思表示したかったのでこの記事と一緒に公開しました。</p>
<p>外からはプロフィールと投稿ページは見れるようになっています。僕のプロフィールページはこちら:<br>
<a href="https://www.mewst.com/@shimbaco">https://www.mewst.com/@shimbaco</a></p>
<p>Twitterにクロスポイントする機能は先に追加したので、とりあえず今はしょぼい投稿専用のTwitterクライアントとして機能します。
しばらくツイートしてこなかったけど、これからはMewstを経由してツイートしようかなと思っています。</p>
<p>今後のMewstのアップデートについてはこのブログや<a href="https://twitter.com/joinmewst">MewstのTwitterアカウント</a>などでお知らせしていきたいです。</p>
<p>この記事を書いているとき、GitHubのプロフィールと同じように https://mewst.com/@shimbaco.atom というURLにアクセスしたらAtomフィードが出力されるようにすればRSSリーダーで読めるようになるので、
アルファ版の状態でも外部にお知らせする手段として使えそうだなと思い始めたので機能追加しようと思いました。マイクロブログ開発すごく楽しいです。</p>
<p>ベータ版に向けて動き始めたMewstをよろしくお願いします。</p>
<p><a href="https://www.mewst.com">https://www.mewst.com</a></p>
</summary>
    </entry>
  
    <entry>
      <title>shimba.co をCrystalで作り直した</title>
      <link href="https://shimba.co/2022-12-30-shimbaco-on-crystal" />
      <id>tag:2022-12-30-shimbaco-on-crystal</id>
      <updated>2022-12-30 00:00:00 UTC</updated>
      <summary><p>このサイト、ほとんど更新していないのに何度作り直すんだ…という感じだけど作り直した。</p>
<p>今まで <a href="https://write.as">Write.as</a> というブログホスティングサービスを利用して公開していた。
Webブラウザから雑に記事を書いて公開できるのが楽で良かったんだけど、スタイルの調整などは少しやりづらかった。
最近はGitHubのリポジトリ上でファイルを作ったり編集できたりするので、
Markdownファイルをリポジトリに置いてWebブラウザからファイルを編集すればブログホスティングサービスを利用するのと大差ないのでは？と思い始めた。</p>
<p>作り直すにあたり<a href="/2018-02-24-hello-world-again">以前みたいに</a>Jekyllなどの静的サイトジェネレータを使うのも良いかもと思ったが、
最近また<a href="https://crystal-lang.org">Crystal</a>に興味が出てきたので、
練習がてら<a href="https://kemalcr.com">Kemal</a>というCrystal製のWebフレームワークを使ってページを作ることにした。
このサイトのリポジトリは<a href="https://github.com/shimbaco/shimba.co">こちら</a>。
言語やフレームワークの勉強のために個人サイトを作り直すというのは結構アリかもしれない。</p>
<p>CSSフレームワークには<a href="https://getbootstrap.com">Bootstrap</a>を使い、ホスティングには<a href="https://fly.io">Fly.io</a>を使用している。
GitHub Actionsでmainブランチに変更があったらFly.ioにデプロイするようにしているので、
GitHubのページからブログ記事をコミットしたらデプロイされて参照できる環境になった。
Fly.ioは今回初めて使ったんだけど、デプロイは簡単にできるしTLSの証明書もシュッと作れるしで体験良かった。</p>
<p>あと bojovs.com というドメインでやっていたころのブログ記事もこれを機に引っ越した。
旧URLにアクセスされたら shimba.co ドメインの該当パスにリダイレクトするようにしている。
昔の記事が参照できなくなっていたのが少し気になっていたので、直せて良かった。</p>
</summary>
    </entry>
  
    <entry>
      <title>shimba.co の見た目を少し変えた</title>
      <link href="https://shimba.co/2021-09-23-update-shimbaco" />
      <id>tag:2021-09-23-update-shimbaco</id>
      <updated>2021-09-23 00:00:00 UTC</updated>
      <summary><p><a href="https://shimba.co/2021-09-23-thank-you-stella">Stella の日報を持ち帰る</a>ときに、このブログの見た目が微妙だな〜と思ったので少し変えた。</p>
<p><a href="https://write.as/themes/riley">Riley</a> というテーマが公開されていたので、それを使用している。トップページがシンプルになって良い。あと <a href="https://shimba.co/about">About</a> という自己紹介ページも用意した。</p>
<p>最初は write.as から <a href="https://github.com/shimbaco/shimba.co">github.com/shimbaco/shimba.co</a> に戻そうかと思ったけど、Webブラウザから雑に投稿できる今の形のほうが楽で良いなと思ったので、現状維持することにした。</p>
</summary>
    </entry>
  
    <entry>
      <title>Stella に書いた日報を shimba.co に持ち帰った</title>
      <link href="https://shimba.co/2021-09-23-thank-you-stella" />
      <id>tag:2021-09-23-thank-you-stella</id>
      <updated>2021-09-23 00:00:00 UTC</updated>
      <summary><p>2年くらい前に <a href="https://stella-app.jp">Stella</a> という日報サービスに日報を書いていたんだけど、自分が書いた文書を一カ所にまとめておきたい気持ちが出てきたので持ってきた。</p>
<p>10日分くらいしか書かなかったし、あんまり日報の習慣が根付かなかったな…。またやる気になったらやりたい。</p>
</summary>
    </entry>
  
    <entry>
      <title>日報 (2019-10-20)</title>
      <link href="https://shimba.co/2019-10-20" />
      <id>tag:2019-10-20</id>
      <updated>2019-10-20 00:00:00 UTC</updated>
      <summary><p>(<a href="https://stella-app.jp">Stella</a> に書いた日報の持ち帰りです)</p>
<p>久しぶりの日報になってしまった。先週の平日はあまり作業できなかった…。</p>
<h2>個人開発 (Annict)</h2>
<ul>
<li>PostgreSQL 10.10 から11.5にアップデートした</li>
<li>前々から直そうと思っていたテーブル名やカラム名などの変更をいくつかした</li>
<li>Annict DBにいくつか変更を加えた
<ul>
<li><a href="https://annict.jp/forum/posts/524">Annict DBに放送予定の日時がずらせる機能の追加などをしました - Forum | Annict</a></li>
</ul>
</li>
<li>バグ修正</li>
</ul>
<p>土曜日からやり始めたものもあるから今日1日でこれだけやったわけではない。(日報とは…)
この土日は色々やれた気がする。</p>
<h2>風邪</h2>
<p>ひいてたんだけど、薬飲んで寝てたら治った。💊</p>
</summary>
    </entry>
  
    <entry>
      <title>日報 (2019-10-13)</title>
      <link href="https://shimba.co/2019-10-13" />
      <id>tag:2019-10-13</id>
      <updated>2019-10-13 00:00:00 UTC</updated>
      <summary><p>(<a href="https://stella-app.jp">Stella</a> に書いた日報の持ち帰りです)</p>
<h2>Annict</h2>
<p>不具合のお問い合わせを頂いてそれを直したり、テストを書いたりしていた。テストを書いているときにバグを見つけてついでに直せたのが良かった。ちょっとずつカバレッジ上げていこう。</p>
</summary>
    </entry>
  
    <entry>
      <title>日報 (2019-10-12)</title>
      <link href="https://shimba.co/2019-10-12" />
      <id>tag:2019-10-12</id>
      <updated>2019-10-12 00:00:00 UTC</updated>
      <summary><p>(<a href="https://stella-app.jp">Stella</a> に書いた日報の持ち帰りです)</p>
<h2>Annict</h2>
<p>テストの改修を始めた。RSpecからMinitestに乗り換えつつ、もう少しカバレッジを上げていきたい。ついでに設定周りも見直していて、少しすっきりしそう。</p>
<h2>macOS Catalina</h2>
<p>家のマシンをアップデートしてみた。今のところ特に問題無さそう。新生Twitter for Macを使ってみたくてアップデートしたんだけど、使ってみてなるほど〜となってTweetDeckに戻った。</p>
<h2>台風</h2>
<p>幸い住んでいるところに大きな被害はなかった模様。蓄えた食料が余り気味なので残りの休みで消化しよう。</p>
</summary>
    </entry>
  
    <entry>
      <title>日報 (2019-10-08)</title>
      <link href="https://shimba.co/2019-10-08" />
      <id>tag:2019-10-08</id>
      <updated>2019-10-08 00:00:00 UTC</updated>
      <summary><p>(<a href="https://stella-app.jp">Stella</a> に書いた日報の持ち帰りです)</p>
<h2>Annict</h2>
<p>お問い合わせ対応を何件かした。新しい期が始まったタイミングは毎度人が多くなり、その分お問い合わせも多くなる傾向がある。ありがたい。
でもしばらくすると人がいなくなりがちなので、継続的に使ってもらえるような何かにならないと。(と思い始めて早数年…)</p>
<h2>11月初めの3連休</h2>
<p>11月1日 (金) に有給休暇をもらい、4連休の錬成に成功した。11月3日は<a href="https://toyamarb.github.io/toyama-rubykaigi01/">富山Ruby会議</a>なので、金曜日から木崎湖に行き、3日までに糸魚川を経由して富山入りしようかと思っている。一度大糸線で糸魚川まで行ってみたかったのでとても楽しみ。</p>
</summary>
    </entry>
  
    <entry>
      <title>日報 (2019-10-06)</title>
      <link href="https://shimba.co/2019-10-06" />
      <id>tag:2019-10-06</id>
      <updated>2019-10-06 00:00:00 UTC</updated>
      <summary><p>(<a href="https://stella-app.jp">Stella</a> に書いた日報の持ち帰りです)</p>
<h2>Annict</h2>
<p>Rails 5.2から6.0にアップデートした。AnnictはRails 4.1のころからコツコツとアップデートしているけど、今回が一番スッと上げられたかもしれない。(まだ問題に気づいていないだけかもしれないけど…)</p>
<p>あとは今日の朝方リリースしたもののバグ修正だったりリリースノートを書いたりした。</p>
<ul>
<li><a href="https://annict.jp/forum/posts/475">作品ページが少し変わりました - Forum | Annict</a></li>
<li><a href="https://annict.jp/forum/posts/476">広告を表示しないことにしました - Forum | Annict</a></li>
</ul>
<p>作品ページのリニューアルは難産だったけど、基礎はできたのでこれからはスムーズに開発できそう。</p>
<p>お問い合わせの対応は一部できたけど全部はできなかったので、明日引き続き対応します。🙏</p>
</summary>
    </entry>
  
    <entry>
      <title>日報 (2019-10-05)</title>
      <link href="https://shimba.co/2019-10-05" />
      <id>tag:2019-10-05</id>
      <updated>2019-10-05 00:00:00 UTC</updated>
      <summary><p>(<a href="https://stella-app.jp">Stella</a> に書いた日報の持ち帰りです)</p>
<h2>Annict</h2>
<p>いくつかやっていた。</p>
<ul>
<li>広告削除の続き</li>
<li>gemのアップデート作業</li>
<li>Ruby 2.6.5にアップデート</li>
<li>Font Awesomeの読み込み方法変更</li>
<li>関連商品機能の削除</li>
</ul>
<p>これらは深夜アニメ組が寝静まったころリリースする。
他にもやっていたけどうまいこといかなかったので、明日以降もやっていく。</p>
<ul>
<li>CircleCIからGitHub Actionsへの移行
<ul>
<li>Railsが動くコンテナからPostgreSQLが動くコンテナに接続できないっぽい</li>
</ul>
</li>
<li>Rails 6.0にアップデート
<ul>
<li>System spec周りでコケる</li>
</ul>
</li>
</ul>
</summary>
    </entry>
  
    <entry>
      <title>日報 (2019-10-03)</title>
      <link href="https://shimba.co/2019-10-03" />
      <id>tag:2019-10-03</id>
      <updated>2019-10-03 00:00:00 UTC</updated>
      <summary><p>(<a href="https://stella-app.jp">Stella</a> に書いた日報の持ち帰りです)</p>
<h2>Annict</h2>
<p>データ登録の依頼が来ていたので少し対応した。まだ終わっていないので週末やる予定。</p>
<h2>IIJmio</h2>
<p>無事MNPの転入手続きが完了して利用し始めた。ソフトバンク、今までありがとう。アメリカに対して無力な僕にとってアメリカ放題は最高のサービスだった…。</p>
<h2>富山Ruby会議01</h2>
<p>参加することにした。</p>
<p><a href="https://toyamarb.github.io/toyama-rubykaigi01/">富山Ruby会議01</a></p>
<p>今年の1月に気が高まって氷見まで寒ブリを食べに行くことがあったので、今年2回目の富山になる。楽しみ。</p>
</summary>
    </entry>
  
    <entry>
      <title>日報 (2019-10-02)</title>
      <link href="https://shimba.co/2019-10-02" />
      <id>tag:2019-10-02</id>
      <updated>2019-10-02 00:00:00 UTC</updated>
      <summary><p>(<a href="https://stella-app.jp">Stella</a> に書いた日報の持ち帰りです)</p>
<h2>Annict</h2>
<p>サイト上に掲載している広告を取り除く作業を始めた。自分が見たくないものを人に見せているところに後ろめたさがあった。広告自体をうまいことコンテンツにできれば良いけど、単にアドセンスを貼っただけみたいな広告は他の本当に見せたいものの邪魔になるだけだなと思う。
収益はサポーターからの寄付だけになるけど、果たしてアニメ視聴記録サービスに月数百円出しても良いよと思ってくれる人は世界に何人いるんだろうか…。</p>
<h2>IIJmio</h2>
<p>SIMカードが届いた。MNP転入の手続きをしようと思ったら、手続きに必要な電話の受付時間が19時までで無事死亡。受付終わるの早くない…？裏に人がいるのか…？明日の朝再チャレンジする。</p>
<h2>コンビニ</h2>
<p>今まで家からよく行っていたコンビニよりも近くに別のコンビニがあることを知った。人の往来も少なそうで便利そう。もう今の家に住み始めて6, 7年経つけど、周囲の情報何も知らないな…。</p>
</summary>
    </entry>
  
    <entry>
      <title>日報 (2019-09-30)</title>
      <link href="https://shimba.co/2019-09-30" />
      <id>tag:2019-09-30</id>
      <updated>2019-09-30 00:00:00 UTC</updated>
      <summary><p>(<a href="https://stella-app.jp">Stella</a> に書いた日報の持ち帰りです)</p>
<h2>Annict</h2>
<p>何件かデータ登録のお問い合わせを頂いていたので対応した。地方局の放送予定の管理は難しい…。秋アニメのエピソードが登録され始めて秋っぽくなってきた。</p>
</summary>
    </entry>
  
    <entry>
      <title>Stellaで日報を書くことにした</title>
      <link href="https://shimba.co/2019-09-29-stella" />
      <id>tag:2019-09-29-stella</id>
      <updated>2019-09-29 00:00:00 UTC</updated>
      <summary><p>https://stella-app.jp/user?id=F2FhnXtY8uVVopWoD0gjDfvkdO83</p>
<p>Write.as はあまり日報を書くのに向いていないかな…と思ったのでStellaで書き始めることにした。このブログはもう少し込み入った話題について書くときとかに利用しよう。(と思いつつあまり書くこともなさそう…)</p>
</summary>
    </entry>
  
    <entry>
      <title>日報 (2019-09-29)</title>
      <link href="https://shimba.co/2019-09-29" />
      <id>tag:2019-09-29</id>
      <updated>2019-09-29 00:00:00 UTC</updated>
      <summary><p>(<a href="https://stella-app.jp">Stella</a> に書いた日報の持ち帰りです)</p>
<h2>Stella</h2>
<p>デビューした。最初は<a href="https://shimba.co">自分のブログ</a>で日報を書こうと思っていたけど、あまりしっくり来なかったのでこちらに書いていくことにした。 https://stella-app.jp/new にアクセスするだけで日付とかがタイトルに挿入されて、日報に特化している感じが良い。日報でやったった感を出すために開発とか頑張るみたいなサイクルを回していけたらと思う。日報ドリブン開発。</p>
<h2>Annict</h2>
<p>TypeScriptの型チェック周りでエラーになってた箇所を修正したり、CIでテストが通るようにしたりした。</p>
<p><a href="https://github.com/annict/annict/pull/2240">Fix spec by shimbaco · Pull Request #2240 · annict/annict</a></p>
<p>TypeScriptはドキュメントを斜め読みして雰囲気で書いてる状態なので、基本的なところからちゃんと勉強したい。</p>
<p>あとはAnnictのタスクの整理もした。GitHub Projectsで管理している。</p>
<p><a href="https://github.com/orgs/annict/projects/1">GitHub Projects</a></p>
<p>2019年秋アニメが放送されている時期はリファクタリングをメインにやっていきたい。昔使っていたけど今はどこからも参照されていない謎ファイルとかが残ってたりもするので、そのあたりの掃除も…。</p>
</summary>
    </entry>
  
    <entry>
      <title>日報 (2019-09-28)</title>
      <link href="https://shimba.co/2019-09-28" />
      <id>tag:2019-09-28</id>
      <updated>2019-09-28 00:00:00 UTC</updated>
      <summary><p>このブログ、ブログエンジンを移行したみたいな内容の記事がほとんどで、割りとまじめに書かれた記事も今年の1月のものしかなく、全く更新してこなかった。もうちょっと日々の活動を記録しようと思い、日報を書こうかなと思い始めた。当初は <a href="https://stella-app.jp/">Stella</a> という日報サービスを利用しようかと思ったが、このブログのことを思い出したのでこちらに書くことにした。たぶん不定期になるけどちょっとずつ更新していこう。</p>
<h2>Annict</h2>
<p>相変わらず作品ページのリニューアル作業をしている。少なくとも3, 4ヶ月くらいはやっている。</p>
<p><a href="https://github.com/annict/annict/pull/2197">作品ページのリニューアル by shimbaco · Pull Request #2197 · annict/annict</a></p>
<p>取り組み始めたときはStimulusを使っていて、サーバサイドでデータを取得してページを表示していた。結構良いところまで実装したんだけど、クライアントサイドJSが関わるところを実装しているときに「もういっそ全部クライアントサイドJSで実装したほうが良いのでは？」と思い、Vue.jsで実装し直した。head要素内はSEOとかのためにサーバサイドでレンダリングし、body要素内は全てVue.jsでレンダリングするようにした。ページ内にいろいろな要素があり思ったよりも実装がしんどかったけど、もう少しで公開できる状態まで持っていけそう。今日は細かいバグの修正をいくつかした。</p>
<h2>Softbank -&gt; IIJmio</h2>
<p>固定費を減らそうと思い、重い腰を上げてIIJmioにMNP転入を試みている。すでにIIJmioのSIMを1枚持っているので、もう1枚追加で注文した。早く届いてくれー！</p>
</summary>
    </entry>
  
    <entry>
      <title>個人サイトをSvbtleにした</title>
      <link href="https://shimba.co/2019-01-06-hello-world-again-and-again" />
      <id>tag:2019-01-06-hello-world-again-and-again</id>
      <updated>2019-01-06 00:00:00 UTC</updated>
      <summary><p><code>shimba.co</code> というドメインで自分のホームページを公開していたんだけど、それを<a href="https://svbtle.com">Svbtle</a>で運用することにした。<a href="/2018-02-24-hello-world-again">一年くらい前にJekyllで運用するようにした</a>んだけど、メンテが地味に面倒になったのでSaaS (と言って良いのかな？) を利用することにした。Jekyll時代のページもブログと数個の外部リンク (TwitterとかGitHubとかへのリンク) くらいしかコンテンツが無かったので、サイト全体をSvbtleに変えても特に問題なかった。</p>
<p>Svbtleは有料のブログプラットフォームで、有料なところとシンプルなデザインが気に入った。無料で提供しているところはどうしても広告みたいなもので収益化しようとするので、広告とかPV増幅装置みたいなものでページがワチャワチャしがちで厳しい。Svbtleは広告が表示されないしシェアボタンなどの設置も任意に設定できるのでページがすっきりして良い。ほとんど更新しないサイトに月数ドル払うのはどうなんだろ…とも思ったけど、こういうプラットフォームは持続してほしいし、払ったからには何かしら更新しないと…という意識が芽生えると良いなということでお布施した。</p>
<p>たまに更新できたら良いな。</p>
<p><strong>追記 (2019年1月6日 15時18分)</strong>: <a href="https://svbtle.com/help/custom_domain">HTTPSでアクセスするようにするには管理者にメールを送る必要がある</a>ということで、この記事を書いたあとHTTPSでアクセスできるようにしてというメールを送ったけど返事が来ない。管理者ー！早く来てくれー！</p>
<p><strong>追記 (2019年1月6日 19時36分)</strong>: 全然返事が来ないのでCloudFrontをかまして無理やりHTTPS化した。RSSフィードのURLとか <code>canonical</code> タグのURLがHTTPのままなのが気になるけど、一時的な対応ということで。😏</p>
<p><strong>追記 (2019年2月2日 12時54分)</strong>: 相変わらず返事が無いので「<a href="https://write.as/">Write.as</a>」に乗り換えることにした。</p>
</summary>
    </entry>
  
    <entry>
      <title>Annictを作る人として軸がぶれていた</title>
      <link href="https://shimba.co/2019-01-06-i-was-a-bure-bure-ningen" />
      <id>tag:2019-01-06-i-was-a-bure-bure-ningen</id>
      <updated>2019-01-06 00:00:00 UTC</updated>
      <summary><p><a href="https://svbtleusercontent.com/w4zANYWCr4ZgyYKsFUUVzN0xspap.jpg"><img src="https://svbtleusercontent.com/w4zANYWCr4ZgyYKsFUUVzN0xspap_small.jpg" alt="kizaki.jpg" /></a></p>
<p>(この湖は軸がぶれてない。素敵。)</p>
<p>2019年に入ってから一週間くらい経つけど去年の思い出話を書く。</p>
<p>去年の後半はAnnictに対して表立った改修がほとんどできなかった。下の画像は2019年1月6日現在のお知らせ一覧だけど、6月に更新を行ってから12月末になるまで更新が途絶えている。(7月のお知らせは機能停止のお知らせなのでノーカンとしている)</p>
<p><a href="https://svbtleusercontent.com/o6fCnnokk9ZfbWbym2gM820xspap.png"><img src="https://svbtleusercontent.com/o6fCnnokk9ZfbWbym2gM820xspap_small.png" alt="Annict 2019-01-06 06-36-37.png" /></a></p>
<p><a href="https://github.com/annict/annict">github.com/annict/annict</a> も6月くらいから低迷している。</p>
<p><a href="https://svbtleusercontent.com/a9nqhxEX2DVeTfeueDbYRL0xspap.png"><img src="https://svbtleusercontent.com/a9nqhxEX2DVeTfeueDbYRL0xspap_small.png" alt="annict 2019-01-06 06-29-50.png" /></a></p>
<p>6月くらいから何をしていたかと言うと、Annictのシステムを一新する作業を始めていた。今思えば「V3作り始めます宣言」をDiscordに投下してから軸がぶれ始めたと思う…。
(AnnictのDiscordサーバはこちらです: https://discord.gg/PVJRUKP)</p>
<p><a href="https://svbtleusercontent.com/38bxHnooKUYQvRW2UTZTMb0xspap.png"><img src="https://svbtleusercontent.com/38bxHnooKUYQvRW2UTZTMb0xspap_small.png" alt="#dev - Discord 2019-01-06 06-33-14.png" /></a></p>
<p>当初は下記のような構想を考えていた。</p>
<ul>
<li>Railsで作られている現行システムをElixir/Phoenixで書き直す</li>
<li>フロント部分を <a href="https://github.com/annict/annict">github.com/annict/annict</a> とは別のリポジトリにして、バックエンドとフロントエンドを完全に分ける</li>
<li>フロントエンドとバックエンドとのやり取りには外部にも公開するGraphQL APIを使用してドッグフーディングする</li>
</ul>
<p>その後Elixirよりしっくり来る言語は無いかなと思い始めて<a href="https://reasonml.github.io/">Reason</a>とか<a href="https://crystal-lang.org/">Crystal</a>を触ったものの、Annictを作り直すにはどの言語も色々な車輪を再発明する必要があることがわかり、やっぱりRailsが一番！みたいな気持ちになったりとフラフラしていた。フロント側もTypeScriptを導入するしないを考えたり、Reasonを触り始めたこともあってVue.jsからReactに乗り換えようかなみたいなことを考えたりしてフラフラしていた。インフラ周りではApp EngineやAWSに移行できないかの調査を始めたり、やっぱりPaaSとかIaaSは値段が高いなと思い始めてDigitalOceanで運用しようとしたりしていた。どれも道半ばで挫折している。</p>
<p>Annictをどう作り直すかでフラフラしている中、はてなブックマーク (以下はてブ) の代替を目指すソーシャルブックマークサービスを作り始めたりもしていた。はてブを使い続けるのが厳しくなったというのもあるけど、Annictをどう作り直すかを悶々と考えるうちに別のことがしたくなったというのが本音だと思う。</p>
<blockquote>
<p>平成も終わろうとしているこのご時世にソーシャルブックマークサービスを作り始めてる。タグ管理できるHBFavみたいな感じを目指してる。リリースまで漕ぎ着けられると良いな〜</p>
<p>https://twitter.com/shimbaco/status/1066359691742130177</p>
</blockquote>
<p>こんな感じで軸がブレブレになっていたんだけど、秋アニメが豊作だったからか目立った更新をしていない期間も利用者が増加したり (更新 = 利用者増加とは思っていないけど) Annictの可能性を再認識する機会があったりで、低迷していたモチベーションが12月頃からぐーんと上がった。再び考えた結果以下のようにやっていくことにした。</p>
<p><strong>Railsを使い続ける。</strong> 以前から触っていて使い慣れているし、エコシステムが成熟しているから現状Railsが一番楽に作れる。</p>
<p><strong>Herokuを使い続ける。</strong> 時間はお金より大切、なので。</p>
<p><strong>一気に書き直そうとせず、ページやコンポーネントごとに少しずつ書き直していく。</strong> 昔は機能やページが少なかったから一気に書き直すこともできたけど、その後いろいろと追加された今では難しいことがわかった…。</p>
<p><strong>はてブでブックマークする習慣を断つ。</strong> もともと厳しさを感じる箇所がブックマーク周りだったので、「ブックマークしなければ新しくソーシャルブックマークを作らなくて済むじゃん」という考えに至り習慣を断つことにした。はてブを利用しているときは何でもかんでもブックマークしていたけど、今はあとから見返すことがありそうなページだけ<a href="https://getpocket.com">Pocket</a>に保存するようにしている。<a href="https://www.swarmapp.com">Swarm</a>のチェックインみたいなノリでブックマークを楽しんでいたから今の運用だと物足りないんだけど、きっと慣れる…はず。</p>
<p>GraphQL APIを内部でも使用してドッグフーディングしたい気持ちは今も変わっていないので、ページごとにAPIを充実させて少しずつ作り直していこうと思っている。</p>
<p>ここまでが去年の終わり頃にぼんやりと考えていたことで、その後年末に「<a href="https://developers.annict.jp">Annict Developers</a>」を公開したり<a href="https://annict.jp/forum/posts/293">PC版のナビゲーションメニューに改修を入れる</a>などした。今は人物や団体、キャラクターなどの情報が取得できるAPIエンドポイントを作っている。<a href="https://github.com/orgs/annict/projects/3">今年の冬アニメの期間にやることをGItHub Projectsで公開し始めた</a>ので、今後はこれに沿って開発を進めていく。</p>
<p>約5年前から「俺が考える最強のアニメ視聴記録サービス」を求めて作り続けてきたけど、まだまだ完成には程遠い。今年もなるべくそこに近づけるよう無理せず開発を続けていきたい。</p>
</summary>
    </entry>
  
    <entry>
      <title>個人サイトをJekyllとNetlifyで作り直した</title>
      <link href="https://shimba.co/2018-02-24-hello-world-again" />
      <id>tag:2018-02-24-hello-world-again</id>
      <updated>2018-02-24 00:00:00 UTC</updated>
      <summary><p>前回の記事「<a href="/2015-05-05-hello-world">個人サイトを作り直した</a>」から3年近く経っても1本も記事を書いていないのでもはや存在理由がわからない感じですが、また作り直しました。</p>
<p>今回は「<a href="https://jekyllrb.com/">Jekyll</a>」を使いました。最初「<a href="https://gohugo.io/">Hugo</a>」を使おうとしたんですが、設定方法がよくわからなくて挫折…。ファイルをどう配置すれば良いのかがちょっとわかりにくかったです。Jekyllは以前使っていたのでスムーズに設定できました。</p>
<p>コンテンツの配信に「<a href="https://www.netlify.com/">Netlify</a>」を使い始めました。個人利用なら無料だしGitHubと連携してPushすればすぐ反映されるし「Let's Encrypt」によるHTTPS対応もできるしリダイレクトの設定も簡単にできるしで最高です。</p>
<p>せっかく作り直したんだし、これから思うことがあったら更新していきたい…けど更新しないんだろうなあｗ</p>
</summary>
    </entry>
  
    <entry>
      <title>個人サイトを作り直した</title>
      <link href="https://shimba.co/2015-05-05-hello-world" />
      <id>tag:2015-05-05-hello-world</id>
      <updated>2015-05-05 00:00:00 UTC</updated>
      <summary><p>最近、2008年ごろから使っていた「bojovs」というハンドルネームをやめて
「shimbaco」という名前に切り替えました。
前の個人サイトは<a href="http://bojovs.com/">bojovs.com</a> というドメインで運用していたので、
今回から<a href="http://www.shimba.co">shimba.co</a> というドメインでやっていくことにしました。</p>
<p>それと、前は「<a href="https://middlemanapp.com/">Middleman</a>」という静的サイトジェネレータを使ってましたが、
今回から「<a href="http://www.metalsmith.io/">Metalsmith</a>」というものを使い始めました。
すごくシンプルで、細かいことも調整しやすいので良い気がします。</p>
<p>Metalsmithを使ったブログ作成話はまた今度ブログに書きたいです。
やりたいことをゴリ押ししたところなんかも少しあるので、その辺も含めて…。
モノ自体は<a href="https://github.com/shimbaco/shimbaco">GitHubで公開しています</a>。</p>
<p>Metalsmithによって生成されたHTMLはAmazon S3に置いて運用しています。
今のところS3へのアップロードはマネジメントコンソールから手でガッと
ドラッグアンドドロップしてる感じなので、Gulpか何かで自動化できたらなと思います。</p>
<p>三日三晩寝ながら作ったこのサイトをよろしくお願いします。
僕はアニメ「のだめカンタービレ」の視聴に戻ります。</p>
</summary>
    </entry>
  
    <entry>
      <title>「Annict」というアニメ視聴記録サービスをリリースしました</title>
      <link href="https://shimba.co/2014-03-10-introducing-annict" />
      <id>tag:2014-03-10-introducing-annict</id>
      <updated>2014-03-10 00:00:00 UTC</updated>
      <summary><p>http://www.annict.com</p>
<p>自分が見た(見る)アニメを記録するWebサービスはすでにいくつもあります。
例えば「<a href="http://animetick.net/">Animetick</a>」や「<a href="http://animita.tv/top">あにみた！</a>」や「<a href="https://qnyp.com/">qnyp</a>」(ドメイン名のアルファベット順) など。
どれもとても良いのですが、個人的にはどれも一長一短な気がしています。</p>
<p>僕は2009年の5月頃から見たアニメを記録し始めていて、見終えた後は必ずどこかしらにその記録をしていました。
(以前はGoogle Drive上で自作したスプレッドシート、最近はqnypでチェックインしてました)
ほぼ毎日使用するツールなので思い入れもそれなりに強く、自分が欲している機能の全てを他の方が開発されているサービスに求めるのは難しいため、「えーい自分で作っちゃえ」という流れになりました。</p>
<p>Annictの機能や雰囲気は「<a href="http://www.annict.com/about">Annictについて</a>」から見ることができます。
まだ追加したい(使いたい)機能はたくさんあるので、コツコツとアップデートしていくと思います。</p>
<p><a href="http://www.annict.com">Annict</a>をよろしくお願いします。</p>
</summary>
    </entry>
  
    <entry>
      <title>Middlemanでブログを作り直した</title>
      <link href="https://shimba.co/2013-11-16-a-whole-new-hello-world" />
      <id>tag:2013-11-16-a-whole-new-hello-world</id>
      <updated>2013-11-16 00:00:00 UTC</updated>
      <summary><p>http://bojovs.com</p>
<p><a href="http://middlemanapp.com/">Middleman</a> とそのプラグインの
<a href="http://middlemanapp.com/blogging/">middleman-blog</a> を使用してブログを作り直した。
今までのブログは自作のRailsアプリだったんだけど、記事をGitで管理したくなったのでやめることにした。</p>
<p>今はGitHub Page上で公開しているけど、プライベートな記事をGitで管理するためにAmazon S3に移すかも。</p>
</summary>
    </entry>
  
    <entry>
      <title>コーディング規約をまとめてみた (Rails編)</title>
      <link href="https://shimba.co/2012-10-16-rails-coding-style" />
      <id>tag:2012-10-16-rails-coding-style</id>
      <updated>2012-10-16 00:00:00 UTC</updated>
      <summary><p>半年ほど前に書いた「<a href="http://bojovs.github.com/2012/04/24/ruby-coding-style/">コーディング規約をまとめてみた (Ruby編)</a>」に引き続き、Railsのコーディング規約もまとめてみました。前回と同じように、できるだけ理由を併記するよう努めました (主観的なものも含まれていますが…)。</p>
<p>気に入らない規約や、この記事に書かれている規約以外にも気をつけていることなどありましたら、コメントなどで教えてもらえると嬉しいです (理由も合わせて書いてくれると助かります)。</p>
<p>Railsのコーディング規約は以下のページを参考にまとめています。</p>
<ul>
<li><a href="http://guides.rubyonrails.org/contributing_to_ruby_on_rails.html#follow-the-coding-conventions">http://guides.rubyonrails.org/contributing_to_ruby_on_rails.html#follow-the-coding-conventions</a></li>
<li><a href="https://github.com/bbatsov/rails-style-guide">https://github.com/bbatsov/rails-style-guide</a></li>
</ul>
<h2>前提</h2>
<p>コード例は「<a href="http://bojovs.github.com/2012/04/24/ruby-coding-style/">コーディング規約をまとめてみた (Ruby編)</a>」をベースに記述します。</p>
<h3>Railsのバージョン</h3>
<p>バージョン3.2系を対象にしています。</p>
<h2>ルーティング</h2>
<p>RESTfulなリソース(<code>resources</code> メソッドを使用したルーティング)に対して新たにrouteを追加する場合は、<code>member</code> や <code>collection</code> を使用します。</p>
<pre><code class="language-ruby"># 悪い例
get 'subscriptions/:id/unsubscribe'
resources :subscriptions

# 良い例
resources :subscriptions do
  get 'unsubscribe', on: :member
end

# 悪い例
get 'photos/search'
resources :photos

# 良い例
resources :photos do
  get 'search', on: :collection
end
</code></pre>
<p><strong>理由:</strong></p>
<ul>
<li><code>resources</code> メソッドのブロック内に記述することで、追加するrouteがそのリソースに結びついているということが明確になるため。</li>
</ul>
<p><code>member</code> , <code>collection</code> ルーティングを複数定義する場合は、ブロック内に記述します。</p>
<pre><code class="language-ruby">resources :subscriptions do
  member do
    post 'subscribe'
    post 'unsubscribe'
  end
end

resources :photos do
  collection do
    get 'explore'
    get 'search'
  end
end
</code></pre>
<p><strong>理由:</strong></p>
<ul>
<li>重複部分がなくなり、見た目がすっきりするため。</li>
</ul>
<p><strong>コメント:</strong></p>
<ul>
<li><a href="https://github.com/thoughtbot/guides/tree/master/style#rails">thoughtbotのプログラミングガイド</a>に、&quot;Avoid member and collection routes.&quot; と書かれているのですが、これは何故なんでしょう…?</li>
</ul>
<p>「Nested routes」は、各モデルの関係を表現するために使用します。</p>
<pre><code class="language-ruby">class Post &lt; ActiveRecord::Base
  has_many :comments
end

class Comments &lt; ActiveRecord::Base
  belongs_to :post
end

# routes.rb
resources :posts do
  resources :comments
end
</code></pre>
<p>「Namespaced routes」は、関係するroutesをグルーピングするために使用します。</p>
<pre><code class="language-ruby">namespace :admin do
  resources :products
end
</code></pre>
<p>「Legacy wild controller route」は使用してはいけません。</p>
<pre><code class="language-ruby"># ダメ! ゼッタイ!
match ':controller(/:action(/:id(.:format)))'
</code></pre>
<p><strong>理由:</strong></p>
<ul>
<li>RESTfulでなくなるため。
<ul>
<li>コントローラ内の全てのアクションにGETメソッドでアクセスできてしまう。</li>
</ul>
</li>
</ul>
<h2>コントローラ</h2>
<p>コントローラ内に複雑なビジネスロジックを記述してはいけません。
ビジネスロジックはモデルやヘルパーに記述し、コントローラ内はリクエストからレスポンスまでの一連の流れを簡潔に表現するようにします。</p>
<p><strong>理由:</strong></p>
<ul>
<li>そのアクションがどのようなことをするのかが理解しやすくなるため。</li>
<li>ビジネスロジックのテストがやりやすくなるため。</li>
</ul>
<h2>モデル</h2>
<p><code>has_many</code>, <code>validates</code> などのクラスメソッドは、モデル定義の最初の部分に記述します。</p>
<pre><code class="language-ruby"># 悪い例 (クラスメソッドがメソッド宣言のあとに呼び出されている)
class User &lt; ActiveRecord::Base
  def follow
  end

  has_and_belongs_to_many :groups
end

# 良い例 (クラスメソッドの呼び出しはモデル定義の最初の部分で行う)
class User &lt; ActiveRecord::Base
  has_and_belongs_to_many :groups


  def follow
  end
end
</code></pre>
<p>各クラスメソッドは機能ごとに一定の順番で記述します。</p>
<pre><code class="language-ruby">class User &lt; ActiveRecord::Base
  # 1番目にアクセッサ関連のクラスメソッドを呼び出す
  attr_accessor :type
  attr_accessible :name, :type

  # 2番目にアソシエーション関連のクラスメソッドを呼び出す
  has_and_belongs_to_many :groups
  has_many :posts

  # 3番目にバリデーション関連のクラスメソッドを呼び出す
  validates :name, presence: true

  # 4番目にNamed scopeを呼び出す
  scope :deleted, where(deleted: true)

  # 5番目に外部ライブラリのクラスメソッドを呼び出す
  # 各外部ライブラリごとに1行空白行を挿入する
  devise :database_authenticatable, :rememberable, :trackable

  has_attached_file :avatar

  # 6番目に before_validation などの、ブロック内が複数行になりうるクラスメソッドを呼び出す
  before_validation do
  end


  # 7番目にクラスメソッドを定義する
  # クラスメソッドの呼び出しと定義の間には2行分の空白行を挿入する
  def self.find_by_full_name
  end

  # 8番目にインスタンスメソッドを定義する
  def full_name
  end
end
</code></pre>
<p>同じ名前のクラスメソッドは一つにまとめて呼び出します。そのとき、アルファベット順で呼び出します。</p>
<pre><code class="language-ruby"># 悪い例1 (2つのhas_manyが一箇所で呼び出されていない)
class User &lt; ActiveRecord::Base
  has_many :comments
  has_and_belongs_to_many :groups
  has_many :posts
end

# 良い例1 (2つのhas_manyが一箇所で呼び出されている)
class User &lt; ActiveRecord::Base
  has_and_belongs_to_many :groups
  has_many :comments
  has_many :posts
end

# 悪い例2 (has_and_belongs_to_manyがhas_manyのあとで呼び出されている)
class User &lt; ActiveRecord::Base
  has_many :comments
  has_many :posts
  has_and_belongs_to_many :groups
end

# 良い例2 (「has_」のあとはそれぞれ「m」と「a」なので、アルファベット順に並べると
# has_and_belongs_to_manyがhas_manyより前に来る)
class User &lt; ActiveRecord::Base
  has_and_belongs_to_many :groups
  has_many :comments
  has_many :posts
end

# 悪い例3 (「:posts」が「:comments」の前で呼び出されている)
class User &lt; ActiveRecord::Base
  has_and_belongs_to_many :groups
  has_many :posts
  has_many :comments
end

# 良い例3 (アルファベット順に並べると(ry )
class User &lt; ActiveRecord::Base
  has_and_belongs_to_many :groups
  has_many :comments
  has_many :posts
end
</code></pre>
<p><strong>理由:</strong></p>
<ul>
<li>そのモデルにどのようなことができるのかが把握しやすくするため。
<ul>
<li>書いてある場所が予測しやすくなる</li>
</ul>
</li>
<li>どこに書けば良いかという迷いを無くすため。</li>
<li>各クラスメソッドの機能ごとの呼び出しの順番は、GitHub上で一番Starが付けられているRailsアプリケーションである
<a href="https://github.com/diaspora/diaspora">Diaspora</a> のモデル定義を参考にしました。
<ul>
<li>アルファベット順に並べることで、全員が同じ場所でそのクラスメソッドを呼び出すようになると思います。</li>
</ul>
</li>
</ul>
<p>できるだけ <code>has_and_belongs_to_many</code> は使用せず、 <code>has_many :through</code> を使用します。</p>
<p><strong>理由:</strong></p>
<ul>
<li>外部キー以外のフィールドも追加することができるため。</li>
<li>中間テーブル上でバリデーションの設定ができるため。</li>
</ul>
<p><code>validates_presence_of</code> などの古いバリデーションメソッドは使用せず、<a href="http://thelucid.com/2010/01/08/sexy-validation-in-edge-rails-rails-3/">&quot;sexy validations&quot;</a> を使用します。</p>
<pre><code class="language-ruby"># 悪い例
class User &lt; ActiveRecord::Base
  validates_presence_of :email, :name
end

# 良い例
class User &lt; ActiveRecord::Base
  validates :email, presence: true
  validates :name, presence: true
end
</code></pre>
<p><strong>理由:</strong></p>
<ul>
<li>そのフィールドに付加するバリデーションの設定が1行で記述できるため。
<ul>
<li>読む側も1行だけ見るだけでそのフィールドに設定されている全てのバリデーション内容が把握できます</li>
</ul>
</li>
</ul>
<p>独自のバリデーションを複数回呼び出すときや正規表現を使用するバリデーションを設定したいときは、独自のバリデーション用のクラスを定義します。</p>
<pre><code class="language-ruby"># 悪い例
class Person
  validates :email, format: { with: /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i }
end

# 良い例
class EmailValidator &lt; ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    record.errors[attribute] &lt;&lt; (options[:message] || 'is not a valid email') unless value =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
  end
end

class Person
  validates :email, email: true
end
</code></pre>
<p><strong>理由:</strong></p>
<ul>
<li>そのバリデーションルールが何を意味しているのかがわかりやすくなるため。</li>
</ul>
<p>独自のバリデーションはそのバリデーションのクラスごとにファイルを作成し、<code>app/validators</code> ディレクトリ以下に格納します。</p>
<pre><code>app/validators
├── email_validator.rb
└── phone_number_validator.rb
</code></pre>
<p><strong>理由:</strong></p>
<ul>
<li>特にありません。。
<ul>
<li>皆さんどこに置いているのでしょうか?</li>
<li><a href="http://stackoverflow.com/questions/5263239/where-should-rails-3-custom-validators-be-stored">この辺り</a>を見ると、<code>lib</code> ディレクトリ以下に置くか <code>app</code> ディレクトリ以下に置くかで意見が分かれているようです。</li>
</ul>
</li>
</ul>
<p>データの検索を行う処理を実装するときは、クラスメソッドを定義せず、Named scopeを使用します。引数が必要な場合は、Ruby 1.9から導入されたlambdaメソッドの省略記法 <code>-&gt;</code> を使用します。</p>
<pre><code class="language-ruby"># 悪い例1 (クラスメソッドを定義している)
def self.published
  where(published: true)
end

# 良い例1
scope :published, where(published: true)

# 悪い例2-1 (クラスメソッドを定義している)
def self.liked_by(person)
  joins(:likes).where(likes: { author_id: person.id })
end

# 悪い例2-2 (lambdaメソッドの省略記法を使用していない)
scope :liked_by, lambda { |person|
  joins(:likes).where(:likes =&gt; {:author_id =&gt; person.id})
}

# 良い例2 (省略記法を使用したほうがタイプ数も少なくすっきりしていて見やすい)
scope :liked_by, -&gt; person {
  joins(:likes).where(likes: { author_id: person.id })
}
</code></pre>
<p><strong>理由:</strong></p>
<ul>
<li>データを検索する処理とデータを操作する処理の見分けが付きやすくなるため。
<ul>
<li><strong>データを検索する処理:</strong> Named scopeで定義</li>
<li><strong>データを操作する処理:</strong> クラスメソッドで定義</li>
</ul>
</li>
</ul>
<p><strong>コメント:</strong></p>
<p><strong>更新 (2012/10/16 20:32):</strong> Rails 4.0から <code>lambda</code> メソッドを使用する記述方法が推奨されます (<a href="http://edgeguides.rubyonrails.org/4_0_release_notes.html#active-record">Ruby on Rails 4.0 Release Notes - &quot;Deprecate eager-evaluated scopes.&quot;</a>)。
「良い例1」は、4.0以降では以下のように記述します。(@pinzolo さんありがとうございます! )</p>
<pre><code class="language-ruby"># 良い例1-1 (Rails 4.0から)
scope :published, -&gt; { where(published: true) }
</code></pre>
<p>モデル内に定義するメソッドは、データを操作するメソッドか、データそのものを返すようにします。それ以外の値を返すときは、ヘルパーやデコレータ (<a href="https://github.com/amatsuda/active_decorator">ActiveDecorator</a> など) を使用します。</p>
<pre><code class="language-ruby">class User &lt; ActiveRecord::Base
  # 悪い例
  # データベースからの値にビューで表示する上で必要なものを付加したい場合は
  # デコレータに記述します
  def full_name
    first_name + last_name + 'さん'
  end

  # 良い例
  def full_name
    first_name + last_name
  end
end
</code></pre>
<h2>マイグレーション</h2>
<p>マイグレーションの記述には、Rails 3.1から導入された <code>change</code> メソッドを使用します。</p>
<pre><code class="language-ruby"># 悪い例
class CreateProducts &lt; ActiveRecord::Migration
  def up
    create_table :products do |t|
      t.string :name
      t.text :description

      t.timestamps
    end
  end

  def down
    drop_table :products
  end
end

# 良い例
class CreateProducts &lt; ActiveRecord::Migration
  def change
    create_table :products do |t|
      t.string :name
      t.text :description

      t.timestamps
    end
  end
end
</code></pre>
<p><strong>理由:</strong></p>
<ul>
<li>ロールバックするためのメソッド (<code>down</code>メソッド) を記述する必要がなくなるため</li>
</ul>
<h2>ビュー</h2>
<p>ビュー内にビジネスロジックを記述してはいけません。ヘルパーやモデルに記述するようにします。</p>
<h2>Assets</h2>
<p>自作のライブラリは <code>lib/assets</code> ディレクトリ以下に配置します。</p>
<p>jQueryやUnderscore.jsなどの外部ライブラリは <code>vendor/assets</code> ディレクトリ以下に配置します。</p>
<h2>Action Mailer</h2>
<p>メール本文内にサイトのURLを表示したいときは、<code>_path</code> メソッドではなく <code>_url</code> メソッドを使用します。</p>
<pre><code class="language-ruby"># 悪い例
You can always find more info about this course
= link_to 'here', url_for(course_path(@course))

# 良い例
You can always find more info about this course
= link_to 'here', url_for(course_url(@course))
</code></pre>
<p><strong>理由:</strong></p>
<ul>
<li><code>_url</code> メソッドはホスト名も返すため。
<ul>
<li>開発環境とプロダクション環境の両方で同じコードが利用できる</li>
</ul>
</li>
</ul>
<p><strong>追記 (2012/10/16 22:03):</strong></p>
<p>各方面からいくつかコメントを頂きました。ありがとうございます!</p>
<p><a href="http://b.hatena.ne.jp/ntaoo/">id: ntaoo</a> さん:「rails guideには引数付きのscopeを定義するよりクラスメソッドにするほうがprefered wayだよと書いてあったような。」</p>
<p>確かに &quot;<a href="http://guides.rubyonrails.org/active_record_querying.html#passing-in-arguments">Ruby on Rails Guides の &quot;13.2 Passing in arguments&quot;</a>&quot; の項に以下のように書いてありました…。知りませんでした…。</p>
<pre><code>&quot;Using a class method is the preferred way to accept arguments for scopes.&quot;
</code></pre>
<p>ただ、引数を要するかどうかを問わず、 <code>ActiveRecord::Relation</code> オブジェクトを返す処理は <code>scope</code> で、それ以外はクラスメソッドで定義する、というように区別したほうが、どのメソッドがクエリメソッドとしてchainableなのかが判別しやすいかも知れません。</p>
<p><a href="https://twitter.com/deeeki">@deeeki</a> さん:「クラスマクロ呼び出しでなぜその順番が妥当かという理由もあれば知りたいところ」</p>
<p><a href="https://github.com/diaspora/diaspora">Diaspora</a> が大体こんな順番で書いているということ以外、特に理由はありません。。
なぜDiasporaがこの順番で書いているのか。推測ですが、「よく定義するクラスメソッド順」で書いたのではないかと考えています。上のほうで定義されているクラスメソッドほどよく定義している気がします。</p>
</summary>
    </entry>
  
    <entry>
      <title>自分用のブログを作りました。</title>
      <link href="https://shimba.co/2012-10-13-hello-world" />
      <id>tag:2012-10-13-hello-world</id>
      <updated>2012-10-13 00:00:00 UTC</updated>
      <summary><p>まだ未完成ですが、最低限欲しかった以下の機能が実装できたので、公開してみました。</p>
<ul>
<li>Markdown形式で記事が書ける機能</li>
<li>記事の非公開機能</li>
<li>非公開な記事もまとめて全文検索できる機能
<ul>
<li>非公開記事は管理者のみ検索可能</li>
</ul>
</li>
<li>シンタックスハイライト
<ul>
<li>これはそんなに重要ではなかった</li>
</ul>
</li>
</ul>
<p>Evernoteとブログを足して2で割った感じの環境で記事を書きたかったのですが、良さ気なサービスが見つからなかったので、勉強がてら自分で作りました。</p>
<p>RSSへの対応など、あったら良いなと思える機能はこれからボチボチと実装していこうかなと思います。</p>
</summary>
    </entry>
  
    <entry>
      <title>コーディング規約をまとめてみた (Ruby編)</title>
      <link href="https://shimba.co/2012-04-24-ruby-coding-style" />
      <id>tag:2012-04-24-ruby-coding-style</id>
      <updated>2012-04-24 00:00:00 UTC</updated>
      <summary><p>色々なところで見かけるコーディング規約を見て意識はしているのですが、
その時の気分で書き方を変えてしまうことが多々あったので、自戒を込めてコーディング規約をまとめてみました。</p>
<p>「なぜこの規約が存在するか」を明確にするために、できる限り理由も併記しています。
ただかなり主観的な部分があるので、あまり意味がないかもしれません…。</p>
<p>「この記事のこの規約は気に入らない。」と思うことがきっとあると思います。
その時はコメント欄などに理由も合わせて書いてくれると嬉しいです。</p>
<p>この記事ではRubyのコーディング規約をまとめています。
近いうちにRailsとCoffeeScriptのコーディング規約もまとめるつもりです。</p>
<p>Rubyのコーディング規約は以下のページを参考にまとめました。</p>
<ul>
<li><a href="https://github.com/styleguide/ruby">https://github.com/styleguide/ruby</a></li>
<li><a href="https://github.com/bbatsov/ruby-style-guide">https://github.com/bbatsov/ruby-style-guide</a></li>
<li><a href="http://www.loveruby.net/w/RubyCodingStyle.html">http://www.loveruby.net/w/RubyCodingStyle.html</a></li>
<li><a href="http://shugo.net/ruby-codeconv/codeconv.html">http://shugo.net/ruby-codeconv/codeconv.html</a></li>
</ul>
<p>ちなみに、Railsのコーディング規約は以下のページを参考にまとめるつもりです。</p>
<ul>
<li><a href="http://guides.rubyonrails.org/contributing_to_ruby_on_rails.html#follow-the-coding-conventions">http://guides.rubyonrails.org/contributing_to_ruby_on_rails.html#follow-the-coding-conventions</a></li>
<li><a href="https://github.com/bbatsov/rails-style-guide">https://github.com/bbatsov/rails-style-guide</a></li>
</ul>
<p>この記事はまだ書き終わっておらず、「あとで書く。」などとなっているところがいくつかあります。
これらは近いうちに追記します。</p>
<h2>前提</h2>
<p>明確な理由がない限り、できるだけ多くのRubyistが採用している書き方でコードを記述します。</p>
<p><strong>理由:</strong></p>
<ul>
<li>他人の書き方に合わせることで、他人のコードが読みやすくなり、自分のコードも読まれやすくなるため。</li>
</ul>
<h2>ソースコードレイアウト</h2>
<p>インデントにはスペースを使用し、幅は2とします。</p>
<p><strong>理由:</strong></p>
<ul>
<li>Ruby界隈ではみんなそうしているため
<ul>
<li>自動生成されたファイルがスペース/インデント幅2であることが多い</li>
<li>タブでインデントしていると、それらをその都度タブに置き換える必要がある</li>
</ul>
</li>
<li>GitHubが、タブをインデント幅8としてソースコード表示しているため
<ul>
<li>GitHub上でソースコードを見るとき、インデントが深すぎて見づらい</li>
</ul>
</li>
</ul>
<p>ファイルのエンコーディングは <code>UTF-8</code> とします。
一行の桁数は80桁までとします。</p>
<p><strong>理由:</strong></p>
<ul>
<li>1行にまとめて記述するよりも、複数行に分割して記述したほうが、段階が追いやすく読みやすいため</li>
<li>1行が長すぎると横にスクロールする必要が出てくるため、読みづらくなる
<ul>
<li>画面分割などで表示される領域が狭いことがある</li>
</ul>
</li>
</ul>
<h2>シンタックス</h2>
<p>以下の部分にスペースを記述します。</p>
<ul>
<li>演算子の前後
<ul>
<li>べき乗の演算子を除く</li>
</ul>
</li>
<li>カンマ、コロン、セミコロンの後ろ</li>
<li>中括弧( { )の前後</li>
<li>中括弧( } )の前</li>
</ul>
<pre><code>sum = 1 + 2 # 演算子の前後
e = M * c**2 # べき乗の演算子の前後にはスペースを入れない
a, b = 1, 2 # カンマの後ろ
1 &gt; 2 ? true : false; puts 'Hi' # セミコロンの後ろ
[1, 2, 3].each { |e| puts e } # 中括弧周辺
</code></pre>
<p><strong>理由:</strong></p>
<ul>
<li>べき乗の演算子の前後にスペースを入れない理由は、乗算の演算子と見分けやすくするため</li>
</ul>
<p>以下の部分にはスペースを記述しません。</p>
<ul>
<li>括弧( ( )、角括弧( [ )の後ろ</li>
<li>括弧( ) )、角括弧( ] )の前</li>
</ul>
<pre><code>some(arg).other
[1, 2, 3].length
</code></pre>
<p><code>case</code> 式と <code>when</code> 節のインデントは同じ深さにします。
ただし、 <code>case</code> 式を変数に代入するときは <code>when</code> 節に合わせず、単純なインデントで記述します。</p>
<pre><code># 良い例1
case
when song.name == 'Misty'
  puts 'Not again!'
when song.duration &gt; 120
    puts 'Too long!'
else
  song.play
end

# 悪い例 (case式を変数に代入するときは、インデントを同じ深さにしない)
kind = case year
       when 1850..1889 then 'Blues'
       when 1890..1909 then 'Ragtime'
       else 'Jazz'
       end

# 良い例2
kind = case year
  when 1850..1889 then 'Blues'
  when 1890..1909 then 'Ragtime'
  else 'Jazz'
  end
</code></pre>
<p><strong>理由:</strong></p>
<ul>
<li><code>case</code> 式と <code>when</code> 節のインデントは同じ深さにする理由:
<ul>
<li>「<a href="http://www.oreilly.co.jp/books/9784873113944/">プログラミング言語Ruby</a>」や
「<a href="http://www.oreilly.co.jp/books/9784873113678/">初めてのRuby</a>」がこの形式を使用しているため。</li>
</ul>
</li>
<li><code>case</code> 式を変数に代入するときは <code>when</code> 節に合わせない理由:
<ul>
<li>変数名が変わったとき、<code>when</code> 節以下のインデントも変える必要があるため。
詳細は「メソッドに渡すパラメータ」の部分で後述します。</li>
</ul>
</li>
<li>追記 (2012/04/28 19:46): この記事を公開した当初は「悪い例」を良い例としていました。
「メソッドに渡すパラメータ」の部分と考え方を統一するため、「良い例2」を追記しました。
<a href="http://bojovs.github.com/2012/04/24/ruby-coding-style/#comment-512139116">m4i</a> さん、ありがとうございます!</li>
</ul>
<p><code>def</code> 式と <code>def</code> 式の間には空行を入れ、<code>def</code> 式内は論理的にまとまった処理の集まりごとに空行を入れます。</p>
<pre><code>def some_method
  data = initialize(options)

  data.manipulate!

  data.result
end

def some_method
  result
end
</code></pre>
<p>メソッドに渡すパラメータは、80桁以上になる場合、メソッド呼び出しの次の行にインデントして表示します。</p>
<pre><code># 悪い例1 (1行が80桁以上。複数行に分割する必要がある)
def send_mail(source)
  Mailer.deliver(to: 'bob@example.com', from: 'us@example.com', subject: 'Important message', body: source.text)
end

# 悪い例2
def send_mail(source)
  Mailer.deliver(to: 'bob@example.com',
                 from: 'us@example.com',
                 subject: 'Important message',
                 body: source.text)
end

# 良い例
def send_mail(source)
  Mailer.deliver(
    to: 'bob@example.com',
    from: 'us@example.com',
    subject: 'Important message',
    body: source.text)
end
</code></pre>
<p><a href="https://github.com/bbatsov/ruby-style-guide">https://github.com/bbatsov/ruby-style-guide</a> では、
「悪い例2」が「good」として紹介されていて、「良い例」が「bad (normal indent)」として紹介されています。
なぜ「悪い例2」を悪い例としたかというと、</p>
<ul>
<li>メソッド名などが変わるたびに、その下に記述されているパラメータのインデント数も変わってしまう</li>
<li>メソッド名の後にパラメータを記述すると、1行が長くなってしまう</li>
</ul>
<p>ためです。例えば、「悪い例2」のメソッド <code>deliver</code> の名前が <code>deliver_to_me</code> などに変わったとき、
「悪い例2」のようなインデントの仕方をすると、<code>from</code> から <code>body</code> までの行のインデントも変える必要が出てきます。
バージョン管理ツールなどでソースコードの変更箇所を記録している場合、
インデントを直しているだけで記録する必要のない箇所も変更箇所として記録されてしまいます。</p>
<p>メソッド定義のとき、引数が無い場合は括弧を省略し、ある場合は括弧を記述するようにします。</p>
<pre><code>def some_method
end

def some_method_with_arguments(arg1, arg2)
end
</code></pre>
<p>できるだけ <code>for</code> 式を使用せず、<code>each</code> メソッドを使用します。</p>
<pre><code>arr = [1, 2, 3]

# 悪い例
for elem in arr do
  puts elem
end

# 良い例
arr.each { |elem| puts elem }
</code></pre>
<p><strong>理由:</strong></p>
<ul>
<li><code>for</code> 式で使用する変数 (上の例でいう <code>elem</code>) が <code>for</code> 式の外からでも呼び出せてしまうため
<ul>
<li><code>each</code> メソッドで使用する変数はブロックスコープ内で宣言されるため、ブロックの内側からでしか呼び出せない</li>
</ul>
</li>
</ul>
<p><code>if/unless</code> 式には <code>then</code> を付加せず記述します。</p>
<pre><code># 悪い例
if some_condition then
end

# 良い例
if some_condition
end
</code></pre>
<p><code>if/then/else/end</code> が1行で書けるような処理の場合は、代わりに三項演算子を使用します。</p>
<pre><code># 悪い例
result = if some_condition then something else something_else end

# 良い例
result = some_condition ? something : something_else
</code></pre>
<p>三項演算子がネストするようなときは、外側の条件分岐を <code>if/else</code> で記述します。</p>
<pre><code># 悪い例
some_condition ? (nested_condition ? nested_something : nested_something_else) : something_else

# 良い例
if some_condition
  nested_condition ? nested_something : nested_something_else
else
  something_else
end
</code></pre>
<p><code>if</code> 式の <code>else</code> 句が必要なく、1行で記述できる場合は、後置 <code>if/unless</code> を使用します。</p>
<pre><code># 悪い例
if some_condition
end

# 良い例
do_something if some_condition
</code></pre>
<p>条件式に否定( ! )は使用せず、<code>unless</code> 式を使用します。</p>
<pre><code># 悪い例
do_something if !some_condition

# 良い例
do_something unless some_condition
</code></pre>
<p><code>unless</code> 式では <code>else</code> 句を使用しません。<code>if</code> 式に書き換えます。</p>
<pre><code># 悪い例
unless success?
  puts 'failure'
else
  puts 'success'
end

# 良い例
if success?
  puts 'success'
else
  puts 'failure'
end
</code></pre>
<p><strong>理由:</strong></p>
<ul>
<li>ややこしくなるため。</li>
</ul>
<p><code>if/unless/while</code> 式の条件部には括弧を使用しません。</p>
<pre><code># 悪い例
if (x &gt; 10)
end

# 良い例
if x &gt; 10
end
</code></pre>
<p>以下のメソッドには括弧をつけません。その他のメソッドには括弧をつけます。</p>
<ul>
<li>Rake, Rails, RSpecなどにある内部DSLとなるメソッド (<code>render</code>, <code>response_with</code> など)</li>
<li>キーワードのように扱われるメソッド (<code>attr_reader</code>, <code>puts</code> など)</li>
<li>属性のようにアクセスされるメソッド</li>
</ul>
<pre><code>class Person
  attr_reader :name, :age
end

temperance = Person.new('Temperance', 30)
temperance.name

puts temperance.age

x = Math.sin(y)
array.delete(e)
</code></pre>
<p>1行で記述されるブロックには中括弧 <code>{...}</code> を使用します。
その1行が複雑だったり横に長かったりする場合や、処理を複数行記述するときは、<code>do...end</code> を使用します。</p>
<pre><code>names = ['Bozhidar', 'Steve', 'Sarah']

# 良い例1
names.each { |name| puts name }

# 悪い例1 (1行で簡潔な処理を do...end 内に記述している)
names.each do |name|
  puts name
end

# 悪い例2 (複雑で横に長い処理を1行で記述している)
names.each { |name| puts sugoku.nagai.shori(fukuzatsu.na.shori(name)) }

# 良い例2 (複雑な処理は複数行に分割する。複数行になるときは do...end を使用する)
names.each do |name|
  name = fukuzatsu.na.shori(name)
  name = sugoku.nagai.shori(name)
  puts name
end
</code></pre>
<p>追記 (2012/04/28 20:40): 「悪い例2」と「良い例2」を追記しました。
<a href="http://bojovs.github.com/2012/04/24/ruby-coding-style/#comment-512139116">m4i</a> さん、ありがとうございます!</p>
<p>ブロックに対してメソッドチェインするときは、中括弧 <code>{...}</code> で囲まれたブロックに対して行います。</p>
<pre><code># 良い例
names.select { |name| name.start_with?(&quot;S&quot;) }.map { |name| name.upcase }

# 悪い例
names.select do |name|
  name.start_with?(&quot;S&quot;)
end.map { |name| name.upcase }
</code></pre>
<p><code>return</code> が不要なときは記述しません。</p>
<pre><code># 悪い例
def some_method(some_arr)
  return some_arr.size
end

# 良い例
def some_method(some_arr)
  some_arr.size
end
</code></pre>
<p>メソッドの仮引数に値を代入するとき、<code>=</code> の両端にスペースを入れます。</p>
<pre><code># 悪い例
def some_method(arg1=:default, arg2=nil, arg3=[])
end

# 良い例
def some_method(arg1 = :default, arg2 = nil, arg3 = [])
end
</code></pre>
<p><code>if</code> 式の条件部では変数の代入を行いません。</p>
<pre><code># 悪い例1
if (v = array.grep(/foo/)) ...

# 悪い例2
if v = array.grep(/foo/) ...

# 悪い例3
if (v = self.next_value) == &quot;hello&quot; ...

# 良い例
v = self.next_value

if v == 'hello' ...
</code></pre>
<p><strong>理由:</strong></p>
<ul>
<li><code>==</code> と見分けがつきにくいため</li>
</ul>
<p><a href="https://github.com/bbatsov/ruby-style-guide">https://github.com/bbatsov/ruby-style-guide</a> では
「悪い例1」と「悪い例3」が良い例として書かれていました。</p>
<p>すでに値が代入されているかもしれない変数の初期化には <code>||=</code> を使用します。</p>
<pre><code>name ||= 'Bozhidar'
</code></pre>
<p>追記 (2012/04/28 20:54):「変数の初期化」から「すでに値が代入されているかもしれない変数の初期化」に修正しました。
<a href="http://bojovs.github.com/2012/04/24/ruby-coding-style/#comment-512139116">m4i</a> さん、ありがとうございます!</p>
<p>真偽値の初期化を行うときは <code>||=</code> を使用してはいけません。</p>
<pre><code># 悪い例
enabled ||= true

# 良い例
enabled = true if enabled.nil?
</code></pre>
<p><strong>理由:</strong></p>
<ul>
<li><code>nil</code> は偽として扱われないため
<ul>
<li>追記 (2012/04/24 13:44): 「Rubyで論理値が必要になった場合、<code>nil</code> は <code>false</code> のように振る舞う (プログラミング言語Ruby P.76)」ため、この理由は間違いでした。
<a href="https://twitter.com/#!/noanoa07/status/194643886067560449">@noanoa07</a> さん、ありがとうございます!</li>
</ul>
</li>
</ul>
<p>メソッド名と開始括弧 ( ( ) の間にスペースを入れてはいけません。もし第一引数で括弧を使用していた場合、メソッドの括弧を必ず入力します。</p>
<pre><code># 悪い例1 (メソッド名と開始括弧の間にスペースが入っている)
p (3 + 2) + 1

# 悪い例2 (メソッド名と開始括弧の間にスペースは入っていないが、第一引数で括弧が使用されている)
p(3 + 2) + 1

# 良い例 (第一引数で括弧を使用していた場合、メソッドの括弧を必ず入力する)
p((3 + 2) + 1)
</code></pre>
<p><strong>理由:</strong></p>
<ul>
<li>メソッドの括弧なのか引数で使用する括弧なのかを明確にするため
<ul>
<li>悪い例1と悪い例2とでは実行結果が異なります。</li>
<li>追記 (2012/04/25 13:22): この記事を公開した当初は、悪い例2を良い例として取り上げていましたが、間違っていたため、書き直しました。
<a href="https://twitter.com/#!/n0kada/status/194980561813635073">@n0kada</a> さん、ありがとうございます!</li>
</ul>
</li>
</ul>
<p>Ruby 1.9では新しいハッシュ記法を使用します。</p>
<pre><code># 悪い例
hash = { :one =&gt; 1, :two =&gt; 2 }

# 良い例
hash = { one: 1, two: 2 }
</code></pre>
<p>Ruby 1.9では <code>lambda</code> メソッドをリテラルで記述します。</p>
<pre><code># 悪い例
lambda = lambda { |a, b| a + b }
lambda.call(1, 2)

# 良い例
lambda = -&gt;(a, b) { a + b }
lambda.(1, 2)
</code></pre>
<p>使用しないブロック引数名は <code>_</code> にします。</p>
<pre><code># 悪い例
result = hash.map { |k, v| v + 1 }

# 良い例
result = hash.map { |_, v| v + 1 }
</code></pre>
<h2>命名ルール</h2>
<p>メソッドと変数には <code>snake_case</code> を使用します。</p>
<p>クラスとモジュールには <code>CamelCase</code> を使用します。
ただし、HTTP, XMLのような単語の頭文字を取った名前はそのまま全て大文字にします。</p>
<p>定数には <code>SCREAMING_SNAKE_CASE</code> を使用します。</p>
<p>返り値が真偽値のメソッドは、<code>Array#empty?</code> のように、名前の最後に <code>?</code> を付加します。</p>
<p><code>self</code> を書き換えるような破壊的なメソッドの名前には、最後に <code>!</code> を付加します。</p>
<p>破壊的なメソッドを定義したとき、可能であれば、同じ返り値を返す非破壊的なメソッドも定義します。</p>
<pre><code>class Array
  def flatten_once!
    res = []

    each do |e|
      [*e].each { |f| res &lt;&lt; f }
    end

    replace(res)
  end

  def flatten_once
    dup.flatten_once!
  end
end
</code></pre>
<p>エイリアスが存在するメソッドは、どちらか一方を使用します。例えば、</p>
<ul>
<li><code>collect</code> より <code>map</code></li>
<li><code>detect</code> より <code>find</code></li>
<li><code>find_all</code> より <code>select</code></li>
<li><code>inject</code> より <code>reduce</code></li>
<li><code>length</code> より <code>size</code></li>
</ul>
<h2>コメント</h2>
<p>あとで書く。</p>
<h2>注釈</h2>
<p>あとで書く。</p>
<h2>クラス</h2>
<p>あとで書く。</p>
<h2>例外</h2>
<p>あとで書く。</p>
<h2>配列、ハッシュ</h2>
<p>文字列が格納されるだけの配列の場合は、 <code>%w</code> を使用します。</p>
<pre><code># 悪い例
STATES = ['draft', 'open', 'closed']

# 良い例
STATES = %w(draft open closed)
</code></pre>
<p>ハッシュはRuby 1.9から追加されたリテラルを使用して記述します。</p>
<pre><code># 悪い例
hash = { :one =&gt; 1, :two =&gt; 2, :three =&gt; 3 } # 今までのハッシュリテラル

# 良い例
hash = { one: 1, two: 2, three: 3 }
</code></pre>
<h2>文字列</h2>
<p>文字列の結合は使用せず、式展開を使用します。</p>
<pre><code># 悪い例
email_with_name = user.name + ' &lt;' + user.email + '&gt;'

# 良い例
email_with_name = &quot;#{user.name} &lt;#{user.email}&gt;&quot;
</code></pre>
<p>式展開やバックスラッシュ記法( <code>\t</code> や <code>\n</code> など) を使用しない場合はシングルクォートを使用します。</p>
<pre><code># 悪い例
name = &quot;Bozhidar&quot;

# 良い例
name = 'Bozhidar'
</code></pre>
<p>大きな文字列を結合する場合は、<code>String#+</code> を使用せず <code>String#&lt;&lt;</code> を使用します。</p>
<pre><code>html = ''
html &lt;&lt; '&lt;h1&gt;Page title&lt;/h1&gt;'

paragraphs.each do |paragraph|
  html &lt;&lt; &quot;&lt;p&gt;#{paragraph}&lt;/p&gt;&quot;
end
</code></pre>
<p><strong>理由:</strong></p>
<ul>
<li><code>String#+</code> は非破壊的なメソッドであるため。<code>String#+</code> は文字列結合するたびに新しい文字列を生成する。
そのため、<code>String#&lt;&lt;</code> のほうが速い。</li>
</ul>
<h2>正規表現</h2>
<p>あとで書く。</p>
<h2>パーセント記法</h2>
<p>配列の中に文字列のみが含まれている場合は <code>%w</code> を使用します。</p>
<pre><code>STATES = %w(draft open closed)
</code></pre>
<p>1行で記述できる文字列で、ダブルクォートと式展開を両方使用している場合は <code>%()</code> を使用します。
複数行に渡る場合はヒアドキュメントを使用します。</p>
<pre><code># 悪い例 (ダブルクォートが記述されていない)
%(This is #{quality} style)
# &quot;This is #{quality} style&quot; が好ましい

# 悪い例 (式展開が記述されていない)
%(&lt;div class=&quot;text&quot;&gt;Some text&lt;/div&gt;)
# '&lt;div class=&quot;text&quot;&gt;Some text&lt;/div&gt;' が好ましい

# 悪い例 (ダブルクォートが記述されていない)
%(This is #{quality} style)
# &quot;This is #{quality} style&quot; が好ましい

# 悪い例 (複数行の文字列になっている)
%(&lt;div&gt;\n&lt;span class=&quot;big&quot;&gt;#{exclamation}&lt;/span&gt;\n&lt;/div&gt;)
# ヒアドキュメントを使用するのが好ましい

# 良い例 (ダブルクォートと式展開が記述されている)
%(&lt;tr&gt;&lt;td class=&quot;name&quot;&gt;#{name}&lt;/td&gt;)
</code></pre>
<p><code>%q</code> , <code>%Q</code> , <code>%x</code> , <code>%s</code> , <code>%W</code> は使用してはいけません。</p>
<p><strong>理由:</strong></p>
<ul>
<li>あとで調べる。
<ul>
<li>追記 (2012/04/28 20:22): <a href="https://github.com/bbatsov/ruby-style-guide">https://github.com/bbatsov/ruby-style-guide</a> に
この記述があったので一応書いているんですが、なぜなんでしょうか?</li>
</ul>
</li>
</ul>
<h2>メタプログラミング</h2>
<p>あとで書く。</p>
<h2>その他</h2>
<p>オプション引数としてハッシュを使用するのは極力避けます。</p>
<p><strong>理由:</strong></p>
<ul>
<li>オプション引数が必要になるメソッドは、そのメソッドの中でいろいろなことをやり過ぎていることが多いため。
メソッドを複数個宣言し、処理を分けたほうが良い。</li>
</ul>
<p>不要なメタプログラミングは避けます。</p>
</summary>
    </entry>
  
    <entry>
      <title>匿名でつぶやきが投稿できるWebサービス「Anoside」をリリースしたよ</title>
      <link href="https://shimba.co/2011-12-25-anoside" />
      <id>tag:2011-12-25-anoside</id>
      <updated>2011-12-25 00:00:00 UTC</updated>
      <summary><p>昨日と今日、以前からちょこちょこと作り続けてきたWebアプリを公開するための作業をしていました。
本当は昨日公開したかったんですが、色々と問題が発生して今ようやく公開できる形となりました。疲れた…。</p>
<p>Anoside: <a href="http://anoside.com/">http://anoside.com/</a></p>
<h2>どんなサービス?</h2>
<p>この記事のタイトル通りで、Twitterに投稿するような短いテキストから
ブログに投稿するような長い文章までを匿名で投稿することができるWebサービスです。</p>
<p>投稿されたポストにはコメントを付けることができます。このコメントももちろん匿名で行うことができますが、
ユーザを判別するためのIDがついています。このIDはポストごとに変わります。
ポストの内容に対して議論などをするときは、完全な匿名よりも、
IDか何かで誰がどのコメントをしたかがわかると良いかなと思い、この機能を付けました。</p>
<p>投稿したポストは「タグ」を付けてカテゴライズすることができます。
タグは他人のポストにも付けることができます。ニコニコ動画のタグ機能みたいな感じです。</p>
<p>ポストやコメント、そしてタグは、誰かがそれらを追加したとき、リアルタイムでこちらの画面にも反映されます。
何も投稿せずただ眺めてるだけでも面白いと思います。</p>
<h2>なぜ作ったの?</h2>
<p>自分の、何の脈絡もなくどうでも良いつぶやきを、匿名で公開できる場所があっても良いと思ったからです。</p>
<p>匿名で何かを投稿するサービスとして、「2ちゃんねる」や「はてな匿名ダイアリー」などがすでにあります。
でも、2ちゃんねるでは板とスレッドという枠のなかで発言しなければならないし、
はてな匿名ダイアリーはある程度自分の考えを文章にしないといけません(そんな気がします)。</p>
<p>Anosideであれば、話題に縛られることなく、そのとき思いついたことをそのまますぐに投稿することができます。</p>
<h2>開発について</h2>
<p>AnosideはNode.js上で動いています。主に以下の技術を利用しています。</p>
<ul>
<li>Express</li>
<li>Socket.IO</li>
<li>node-http-proxy</li>
<li>MongoDB</li>
<li>Redis</li>
<li>Backbone.js</li>
<li>RequireJS</li>
</ul>
<p>これらのものを使用して開発するのは初めてで、しかも、
作ったものを外部に公開すること自体が初めてだったりするので、デプロイの作業がとても大変でした…。
今はまだ、とりあえず使える形で公開している状態なので、先がかなり怖いです。
とりあえず公開して、興味を持ってくれた数人の方に使ってもらえたら嬉しいなという気持ちでいます。</p>
<p>運用方法などのノウハウはこれから勉強していきたいと思います。
どなたか運用の方法を教えてくださると非常に助かります＞＜</p>
<p>あと、AnosideのソースコードはGitHubに公開しています。興味のある方は是非御覧ください。
そして変なところを教えてもらえると嬉しいです。</p>
<ul>
<li><a href="https://github.com/bojovs/anoside">https://github.com/bojovs/anoside</a></li>
<li><a href="https://github.com/bojovs/anoside-sio">https://github.com/bojovs/anoside-sio</a></li>
<li><a href="https://github.com/bojovs/anoside-proxy">https://github.com/bojovs/anoside-proxy</a></li>
</ul>
<p><a href="http://anoside.com/t/anoside-dev">anoside-dev</a>というタグをチェックします。
なのでそのタグを付けてポストしてもらうか、
Twitterのアカウント (<a href="https://twitter.com/anoside">@anoside</a>, <a href="https://twitter.com/bojovs">@bojovs</a>)
にmentionなどを飛ばしてもらえれば反応できます。</p>
<h2>以上</h2>
<p><a href="http://anoside.com/">Anoside</a>をよろしくお願いしますm(__)m</p>
</summary>
    </entry>
  
    <entry>
      <title>VowsとZombie.jsでExpress, MongooseなNode.jsアプリのテストを書いたよ</title>
      <link href="https://shimba.co/2011-09-30-vows-zombie" />
      <id>tag:2011-09-30-vows-zombie</id>
      <updated>2011-09-30 00:00:00 UTC</updated>
      <summary><h2>環境</h2>
<ul>
<li>Node.js 0.4.9</li>
<li><a href="http://expressjs.com/">Express</a> 2.4.6</li>
<li><a href="http://mongoosejs.com/">Mongoose</a> 2.2.2</li>
<li><a href="http://vowsjs.org/">Vows</a> 0.5.11</li>
<li><a href="http://zombie.labnotes.org/">Zombie.js</a> 0.10.1</li>
<li><a href="https://github.com/mikeal/request">request</a> 2.1.1</li>
</ul>
<h2>流れ</h2>
<p>最初に、モデル内のドキュメントを削除するコードと、サーバを起動するコードを記述します。</p>
<p><strong>test/helper.js</strong></p>
<pre><code>var mongoose = require('mongoose')
  , app = require('../app')
  , Post    = require('../models/post').Post
  , User    = require('../models/user').User;

var serverActivity = false
  , models = [Post, User];


process.on('exit', function () {
  // サーバが起動していたら終了する
  if (serverActivity) {
    app.close();
  }
});

module.exports = {

  /**
   * 配列modelsに入っているドキュメントを全て削除する
   */

  initDB: function initDB(callback, count) {
    var cnt = count || 0;
    models[cnt].remove(function () {
      cnt += 1;
      if (cnt === models.length) {
        callback();
      } else {
        initDB(callback, cnt);
      }
    });
  },

  /**
   * サーバが起動していなかったら起動する
   */

  readyServer: function (callback) {
    if (serverActivity) {
      process.nextTick(callback);
    } else {
      serverActivity = true;
      app.listen(3030, function () {
        process.nextTick(callback);
      });
    }
    return;
  }
};
</code></pre>
<p>次に、実際にテストを書いていきます。</p>
<p><strong>test/controllers/posts.test.js</strong></p>
<pre><code>var assert  = require('assert')
  , request = require('request')
  , vows    = require('vows')
  , zombie  = require('zombie')
  , helper = require('../helper')
  , Post = require('../../models/post').Post;

var url = 'http://localhost:3030';


vows.describe('posts').addBatch({
  'GET /': {
    topic: function () {
      helper.readyServer(this.callback);
    },
    'after readyServer': {
      topic: function () {
        request(url + '/', this.callback);
      },
      'should response 200': function (err, res, body) {
        assert.equal(res.statusCode, 200);
      }
    }
  },

  'GET /posts': {
    topic: function () {
      helper.initDB(this.callback);
    },
    'after initDB': {
      topic: function () {
        var post = new Post({ title: 'hello world' });
        post.save(this.callback);
      },
      'after saving post': {
        topic: function (err, post) {
          helper.readyServer(this.callback);
        },
        'after readyServer': {
          topic: function () {
            zombie.visit(url + '/posts', this.callback);
          },
          'should display the post': function (err, browser, status) {
            assert.equal(browser.text('ul#posts li'), 'hello world');
          }
        }
      }
    }
  }
}).export(module);
</code></pre>
<p>12行目から24行目までは、</p>
<ol>
<li>サーバを起動して</li>
<li>http://localhost:3030/ にアクセスしたら</li>
<li>200 が返ってくるべき</li>
</ol>
<p>という処理になっています。26行目から49行目までは、</p>
<ol>
<li>データベースを初期化して</li>
<li>タイトルが「hello world」なポストを保存して</li>
<li>サーバを起動したあとに</li>
<li>http://localhost:3030/postsにアクセスしたら</li>
<li>リスト内に「hello world」が表示されているべき</li>
</ol>
<p>という処理になっています。</p>
<p>Vowsでは、<code>topic</code> という関数の中で <code>this.callback</code> という関数を使うことができます。
この関数を、<code>helper.initDB</code> や <code>helper.readyServer</code> などのコールバック関数を引数に持つ関数に渡し、
その下にさらに <code>topic</code> 関数をネストして記述することで、非同期的な命令を順番に処理させることができるようです。</p>
<p>ただ、結構冗長なコードになっているので、もう少し簡潔に書けないかなあと思っています。
みんなはどうしているんだろう…。</p>
</summary>
    </entry>
  
    <entry>
      <title>Hello World</title>
      <link href="https://shimba.co/2011-09-09-hello-world" />
      <id>tag:2011-09-09-hello-world</id>
      <updated>2011-09-09 00:00:00 UTC</updated>
      <summary><p><a href="http://jekyllrb.com/">Jekyll</a> でブログを書くことにしました。よろしくお願いします。</p>
</summary>
    </entry>
  
</feed>
