Rubyちゃんこんにちわ

子育てエンジニアが綴る

RubyHirobaの難問をQuineで解く

これが解けないと、オレのRubyHirobaが終わらない。という訳で終わらせる。

難問とは?

それがこれ ラーメンバーガー 挑戦者求む!【Ruby】ラーメンバーガー食べたい!│CodeIQ

“ラーメンバーガー食べたい!”と出力するコードを書いてください

一見簡単そうに見えるが、実は奥が深い。

まず日本語をどうにかする必要がある。フォントがインストールされていない環境を想定しなければならない。

次に「出力するコードを書いてください」というところだが、これは一体誰が書くのか?恐らくマシンが書く必要がある。そうQuineでという暗黙条件だ。

これらを組み合わせると、本来の出題意図は「ラーメンバーガー食べたい!と表示されるQuineを書く」ということになる。かなりハードな問題だ。

ちなみに自分は何も考えずに、普通のコードで提出してラーメンバーガーを頂いてしまったが、後でこれらの問題の真意に気づいてRubyHirobaを終えていないことに愕然とした。

Quineとは

そもそもQuineが分からない。Wikipediaによると

自身のソースコードと完全に同じ文字列を出力するプログラムである。

とのこと。なるほど、理解不能だがやってみる価値はありそうだ。

いつも思うのだが、いつも複雑さと戦っている僕らは、なぜ複雑さを求めてしまうのか。

解いてみた

まずフォントを作るところから。ドット絵とか久しぶり。

1
2
3
4
5
6
7
8
9
10
11
12
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1100000000000011111111111111111111111111111111111111111111111111
1111111111111111111111111111111111110011111100111100111111111100
0000000000000000111111111111111111110000110000111111001111111100
1111111111111100110000000000001111111100000011111111111111111100
1111111111111100111111111111111111111100000011111111111111110000
1111111111111100111111111111111111110000110000111111111111000011
1111111111000000111111111111111111000011111100111100001100001111
1111000000001111111111111111111100001111111111111111000000111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111

続いてネット上のいろいろな解説などをもとにQuineを書いてみた。

実行ごとに結果が少しだけ異なるようにしていて、ヒネリは全くないが3回実行するとまた元のコードに戻るようになっている。

以下のようにコマンドすると、それぞれで出力が変わることが分かる。

1
2
3
$ cat ramen.rb | ruby
$ cat ramen.rb | ruby | ruby
$ cat ramen.rb | ruby | ruby | ruby

ということで何とか解けた。ありがとうRubyHiroba。

まとめ

  • CodeIQさん問題ありがとうございます。ラーメンバーガーごちそうさまでした。
  • Quine意外とハマる、数独的な楽しさ。フルスタックエンジニアの逆張りでQuineだけを極めるのもありではないだろうか、いやありえない。
  • いつも複雑さと戦っている僕らは、なぜ複雑さを求めてしまうのか。まだ答えは見つかっていない。。。

参考

いろいろと参考にさせていただきました。これらの資料、記事によってなんとか作れました。ありがとうございます。

終わりに

アスキーアートな簡易Quineを出力するクラスを手元で作ってみた。これでサラッとAA Quineいける!と思ったけど、そもそも01にマッピングしたAAがそこら辺に転がってはいなかった。

この記事とは別にRubyHirobaでLTしてきた話はこちら

RubyHiroba 2013で自作gemについてLTしてきた話

RubyHiroba 2013でLTしてきました。

パンくずリストgemのBreadcrumbleについて紹介

パンくずリストという時点でマニアックな感じですが、自作gemのBreadcrumbleについて紹介してきました。

発表資料はこちらです。ちょっと発表時に分かりにくかったなと思った点をアップデートしています。

あ、ネタばかり考えていて入れ忘れていましたが、Rails 4 もサポートしています。たぶん他のgemもRails 3で動いているので、動くと思いますが。

パンくずリストをDRYにしたくなったときにでも、候補としていただければと思います。

このgemを気に入った方とかそうでない方、そして皆さんにお願いですが、GitHubでスター付けてください。スター付けるまでがRubyHir(略)

LTの反省点はもう少しいいタイミングでドラを鳴らされるようにしたかったなと。ちょっと残念なタイミングで鳴ってしまった、普通に「あっ」とか言ってしまったので。。。要練習です。

その他にもフィードバックなど頂けたら嬉しいです。

最後に

運営関係者の皆様ありがとうございました。スムーズな進行で気持ちよく発表することができました。お忙しい中準備をしていただいて感謝しております。 そして会場提供のMicrosoft様もありがとうございます。ドリンクたくさん頂いてしまいました。

ブログをHeroku cedar stackへ移行し、Octopressもアップデートした

去年のまとめとか書こうと思ったのだけど、そもそもHerokuのstackをcedarに移行してなかったり、Octopressもアップデートしてなくてgistの表示がおかしかったので、これらの対応をしました。 結局これらの作業だけで本日終わりそうなので、まとめとかは全然できておらずですが、悔しいので今日やったことだけサラッとまとめておきます。

Herokuのstack移行

Herokuのstack移行は以下を参考にさせていただいて対応しました。DBも使っていないので、割と手軽に完了。アドレスだけheroku.com -> herokuapp.com に変わってしまったけど、これは仕方ないかな。

HerokuでBambooスタックからCedarスタックへアプリケーションを移行する方法

Herokuもいつの間にかメンテナンスモードがあったり、WebUIがかなーりいい感じになっていたりで素晴らしい。

Octopressアップデート

以下の手順で実行。最初rake generateしていなくて、直らないなーと少しハマってしまった。

1
2
3
4
5
$ git pull origin master
$ bundle install
$ rake update_source
$ rake update_style
$ rake generate

Herokuのstackアプデしたときにサーバもthinにしたので、localでの確認が早くなったりメリットもあったかな。

所感

今回も要所要所で上に書いた以外にも結構ハマりポイントがあったのだけど、割とサラッとその場で解決しつつ対応できた。 昔だったらきっと無理だったろうなと思うと、少しは成長したかなと思う。 反対に成長した分「まだまだだなー」と、世界の広さも感じる。。。

rescue => e で Exception を拾う方法

1
2
3
4
5
begin
  raise Exception.new('exception')
rescue => e
  puts 'do not reach'
end

こういうコードを何度か見たのでブログにも書いておこう。
Rubyのrescueで例外の型を指定しない場合は、StandardErrorとして扱われます。
例外の継承関係は少し古いですが、こちらにある通りです。
大枠はこれで理解できるようにStandardErrorの親クラスとしてExceptionが存在します。
よって上記のコードではExceptionが拾われることはありません。

Exceptionクラスも拾いたい場合は、rescue Exception => e のように Exception クラスを指定する必要があります。

サンプル

結構皆さんいろいろ書いていた。。。でも途中まで書いたので一応アップします。

rescue節で例外の型を指定しない場合に補足できるのはStandardErrorとそのサブクラスだけ
例外処理 Ruby - Wikipedia

Rails勉強会@東京第74回に参加してきた

参加してきました。やったことは以下です。

  • 最近のRails動向確認
  • ActiveRecord周りのソースリーディング

最近のRails動向確認

rails3 および rails4 の CHANGELOG を確認した。ところどころ意味の分からないところは、飛ばしつつ何とかついていきました。
rails3については、脆弱性問題が修正されているので、なるべく最新版使った方がいいんだなというイメージ。
rails4については、ActiveResourceがなくなることと、ActiveRecord のメソッドに deprecated となるものが多かったイメージ。

ActiveRecord周りのソースリーディング

where から SQL の組み立て

大体の流れは以下の通り。

  • where では単に条件を積み重ねた配列を作っていく
  • 条件から AREL オブジェクトを作り、さらに SQL 文にするのは実際に読み込む部分(ex:to_a)

AREL で遅延してSQL発行する部分って、この辺りっぽい。

has_many で何が行われるか

こっちは着いて行くのが結構いっぱいいっぱい。おぼろげに理解できたので、少しだけ Rails に詳しくなれた。

  • has_many から Builder を作って、関連を作る
  • accessor を動的に追加している部分
  • has_one と共通の部分は共通クラスが存在していたりキレイに作られているっぽかった

気づき

Mac の開発環境周りが気になっていたので、@takkanm さんが映していた開発環境が気になりました。 すぐに導入したいなと思ったのは以下3つです。

  • zsh
  • screen
  • git grep

screen はコピーモードがすぐにでも使いたい機能で、git grep もプロジェクト検索で重宝しそう。
zsh とかは前から気にしていたのに、まだ導入していなかった。。。
ということで早速導入してみましたが、なぜ今までやっていなかったのか悔やまれるくらい楽ですね。
zsh のプロンプトカスタマイズは、%ばかりで発狂しそうになったのは内緒です。

Rails 関係なくなっちゃいますが、個人的には開発環境周りがとても勉強になりました。参加して非常に良かった。

Octopress の CSS を編集する

ブログのヘッダタイトル文字が大き過ぎて、iPhone で見ると画面の半分以上がタイトルという残念な表示結果だったので、小さくしてみることにした。
後で忘れそうなので作業記録をつけておく。

Octopress の CSS は sass ディレクトリ以下にあるファイルを編集することで、Octopress が scss から source/stylesheets/screen.css にまとめてくれる。
今回はヘッダの文字列をさくっと小さくしたかったので、/sass/custom/_layout.scss にある以下のコメントアウト部分を編集した。コメントを取って、値を小さくしただけ。

1
2
3
//$header-font-size: 1em;
//$header-padding-top: 1.5em;
//$header-padding-bottom: 1.5em;

CodeSprint Japanに参加してみた

CodeSprint Japan が15時から20時までの5時間行われた。自分が参加したのは半分の2時間半くらい。
Haskell がなさそうだったので、Rubyで参戦してみた。
と思っていたら、Haskell ありました(ーー;
個人的にはかなり難しく、結果は11点で64位。改めて競技プログラミング界のレベルの高さを知りました。

自分の解答状況ですが、2問ソース提出し、両方とも Time limit exceeded で全問解けずでした。Ruby の場合は他の言語より緩めで、16秒の時間制限なのですが、それでも全然足りませんでした。
時間足りていないということは、アルゴリズムの工夫がされていないということで、他の方の解答を参考に何が良くなかったか理解したいのですが、そこは公開されていないようです。

匿名とかでもいいので、他の人のコードが見れると嬉しい。この点は AtCoder がいい感じです。
あるいはテストケースを全て公開してほしいですね。そうすれば、手元でこれが遅いのかって測定できるので。

ちなみに嫌いな数値の解答コードは以下。これで全6問中の3問がタイムオーバー。

Twitter 見ると英語版の過去問題が存在するなどの話がチラホラ。自分の場合は知ってても結果は大して変わらないだろうけど。

Rack の config.ru と Rack アプリについて

Rails のソースを読むにあたって、Rack の動作を前提知識として知っておこうと思う。なぜなら Rails は Rack アプリであるため。
実はちょっと前に調べていたことを忘れていたので、それの復習という意味も兼ねてメモしておきます。

参考にした記事はこちら。
第23回 Rackとは何か(1)Rackの生まれた背景
第24回 Rackとは何か(2)Rackの使い方

config.ru の使われ方

上記記事にも書いてあるように、config.ru に書いたコードは、Rack::Builder の new に渡されるブロックとなります。
ちょっとだけ追ってみましたが、Rack::Builder のクラスメソッド parser_file にて、config.ru を読み込み、initialize メソッドでは読み込んだ中身をブロックとして受けて、instance_eval しています。
このようにして Rack アプリを読み込んでいます。Rails でも同様の仕組みを用いています。

Rack アプリを満たすには

こちらも上記記事に書かれている通りですが、call メソッドがあってレスポンスが返れせれば Rack アプリの条件を満たせます。そのため以下のようなコードでも rackup コマンドで動きます。

このコードは Rack のコメントに載っていたものですが、lambda で生成した Proc オブジェクトは call メソッドを持っているため条件を満たしています。そのため Rack アプリとして扱うことができます。このシンプルさは好きです。
Rails でも、Rails アプリの継承元である Rails::Application や、さらにその継承元である Rails::Engine は call メソッドを定義していますので、Rack アプリとして定義されていることが理解できます。

最後に

ど忘れ結構怖いし時間無駄にするので、こまめにメモしていきたい。

asakusa.rbに行ってきた3回目

浅草の渋谷ヒカリエ開催。

今回からはRubyの集まりということを意識して、Ruby関連の作業をすることにした。
今回のお題は、少し前から始めているRailsのソースリーディング。Railsのコードはかなりあっちこっち飛ぶので、結構読むのが辛い。
RubyにもCでいうところのgtagsあれば楽だろうけど、どうだろう?Rubyで書かれたソースの読み方でオススメがあれば教えていただけると嬉しいです。今のところはVimとPryを使って、Vimで普通に読みつつ、ところどころ使われているライブラリの中身はPryで読むという感じに進めている。
一応 call メソッドがあって、config.ru があるってことでRackアプリなんだなというとこまでは確認。次はルーティングかな。

昨日の集まりは今までに比べると、結構しゃべっていた方で少し情報収集してアンテナ広がった感じがしてよかった。
今時はrbenv使った方がよいとか、mrubyを64KBに載せるとか、githubエンタープライズでの開発とかそんな話など。

@a_matsudaさんからは、EuRuKoの話を展開していただいた。次回の開催地決定方法は、プレゼン式で拍手の音をデシベル計測して決めるとか、とても斬新だった。アイデアの種として、軽くメモっておいた。

Pry を入れてみた

Pry というものを twitter 上で最近見かけるようになったので調べてみた。
irb より便利、メソッドのドキュメントだけでなく、実装の中身を見れたり、何か便利そうだと感じたので早速インストール。

1
gem install pry pry-doc

メソッドの実装調べられるの便利だ。Ruby の組み込み系メソッドだと C の実装が表示されるし、Ruby で書かれたものだと Ruby 実装が表示される。
例えば Sinatra のメソッドを調べてみた例は以下。 クラス内の module などは :: で繋ぎ、method は # で繋ぐことで検索される。

1
2
3
4
5
6
7
8
9
10
[27] pry(main)> show-method Sinatra::Helpers#not_found

From: /.../sinatra-1.3.2/lib/sinatra/base.rb @ line 158:
Number of lines: 3
Owner: Sinatra::Helpers
Visibility: public

def not_found(body=nil)
  error 404, body
end

他にもカスタマイズだとかできるようだけど、しばらくこのまま使ってみよう。

参考

Rubyistよ、irbを捨ててPryを使おう