Category: Ruby

スキャンした電子書籍を{ISBN}.pdfという名前で溜め込んでおいたら、あとから検索性が悪くて絶望した。一覧ページを作るために、「ISBN 検索 API」でググったところ、Amazonと楽天が有力候補(…というかそれ以外にほとんど存在しない)らしい。

普段から使っていることだしAmazonでいいか…と使ってみたら、いろいろやることがあったので手順をメモっておく。

(さらに…)

タイトルがすべてなのだけれど、一覧は意外と見当たらないので作ってみた。

環境

% ruby -v
ruby 1.9.2p136 (2010-12-25 revision 30365) [i686-linux]

概要

  • すべてのクラス定数を取得
  • ancestorsにExceptionクラスをもつものをピックアップ
  • ソートして表示

以下のコードはワンライナーで書いたものを整形してコメントを追記しただけ。参考にしたのはこちら

すべての組み込み例外クラス

以下のようなコードを書いてみた。

puts Object.constants.find_all { |c|
  (cc = Object.const_get(c)) &&         # シンボルからクラス定数を取得
  cc.respond_to?(:ancestors) &&         # ancestorsメソッドを持つ
  cc.ancestors.include?(Exception)      # Exceptionとそのサブクラス
}.sort

(さらに…)

このエントリは「Ruby Advent Calendar jp: 2010」の19日目です。前日の記事はno6vさんの「Time#strftime / Time.at」でした。明日はm_kawatoさんの予定です。


というわけで今年は2つAevent Calendarに参加していて、その2番目の記事。Emacsで書いた記事も細かすぎるネタで恐縮したものだが、こっちは一転して大それた提案になっている。それはそれで恐縮なのだが、おつきあいいただければ幸いである。

hoeとrubygems.org

以前「hoeでrubygemを作り「zenra」を公開する」という記事を書いた。hoeを使ってrubygemsを作り、rubyforgeとrubugems.orgで公開しちゃおうぜ、という内容。しかし、今時はもうrubyforge使わなくてもいいんじゃね?ということで、hoeから直接rubygems.orgにpushする方法を調べてみた。

…と言っても、rakeタスクの中にgem pushしてくれるタスクがあるのでコマンドをひとつ叩くだけ。あらかじめrubygems.orgのアカウントを取得していれば、初回のpush時に登録したメールアドレスとパスワードを入力すればおしまい。

ここでは「pebbles」というgemをpushしてみる。

(さらに…)

LLで全裸ライブラリを作る、というのが流行っているので便乗しよう…と思いたち、どうせ書くならrubygemsにして公開してしまおう、と勢いで作ってみたので作業メモ。ruby版は先に書かれているので、rubygems.orgで公開する手順の方を本題として読んでいただければ。

つくったもの

kwappa’s ruby-zenra at master – GitHub
https://github.com/kwappa/ruby-zenra

zenra | RubyGems.org | your community gem host
https://rubygems.org/gems/zenra

RubyForge: zenra: Project Info
http://rubyforge.org/projects/zenra/

(さらに…)

社内のLTで発表する順番が回ってきた。プログラマとして採用されてるんだしここはひとつ技術ネタで…と振り返ってみたら、そういえば技術ネタで発表した経験がほとんどない。ちょっとドキドキしつつネタを仕込んだ。

スライド

(さらに…)


CLI で動作するアプリを書くときは、たいていコマンドラインから与えられた引数を相手にすることになる。その度に自前でARGVときゃっきゃうふふするロジックを書いてもいいが、手軽で使いやすいライブラリがあるので使ってみるのもいいだろう。

ということで今回はrubygemsから「trollop」のご紹介。今のプロジェクトでも「なぜもっと早く入れなかったか」と悔やみたくなるお得なライブラリである。

導入

gem install trollop

以上。この記事の時点では1.16.2がインストールされた。

このライブラリは1ファイルかつ他に依存もしていないので、直接ダウンロードしてloadpathの通ったところに配置してもいい。最近はbundlerのおかげでgemの整理に気を使う必要は減っているけど。

(さらに…)

概要

MySQLで文字列を検索対象にした場合、一般的なデフォルト設定では大文字・小文字を区別しない。この問題にしっかりハマってしまったので、調査と対策を行ったメモを晒すことにした。

基本的なことがらなのにものすごく長いので「ダイジェスト」を読んでいただければおおむねOKにしてある。検証過程に興味のある方はその続きをどうぞ。

ダイジェスト

MySQLはデフォルトで運用すると文字列の比較 / 並び替えで大文字 / 小文字を区別しない。

大文字小文字を区別して検索するには…

  • テーブル単位
  • カラム単位
  • クエリ単位

…での対応が可能。

データ定義
テーブル単位
-- CREATE TABLE時にテーブルのデフォルト文字コードと照合順序を指定する
CREATE TABLE hoge1 (
  id INTEGER PRIMARY KEY AUTO_INCREMENT,
  str VARCHAR(16)
)
ENGINE = InnoDB,
CHARSET = utf8,
COLLATE = utf8_bin ;
-- ALTER TABLEで文字コードと照合順序を変換する
ALTER TABLE hoge2 CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin ;
カラム単位
-- CREATE TABLE時にカラムの文字コードと照合順序を指定する
CREATE TABLE hoge2 (
  id        INTEGER PRIMARY KEY AUTO_INCREMENT,
  ci_str    VARCHAR(16),
  cs_str    VARCHAR(16) BINARY,
  other_str VARCHAR(16) CHARACTER SET utf8 COLLATE utf8_bin
)
ENGINE = InnoDB ;
-- カラムの文字コードと照合順序を変換する
ALTER TABLE hoge2 CHANGE COLUMN ci_str ci_str VARCHAR(16) COLLATE utf8_bin ;
データ取得
SQL
-- 大文字小文字を区別するカラムで区別せずに検索
mysql> SELECT * FROM hoge2 WHERE LOWER(cs_str) = 'fuga' ;
-- 大文字小文字を区別しないカラムで区別して検索
SELECT * FROM hoge2 WHERE BINARY ci_str = 'fuga' ;
sequel
# 普通にfilterする => カラムのcollationに依存
ruby-1.9.1-p378 > Hoge2.filter(:ci_str => 'fuga').sql<br /> => "SELECT * FROM `hoge2` WHERE (`ci_str` = 'fuga')"<br /><br /># likeでfilter => BINARYキーワードをつけてくれる
ruby-1.9.1-p378 > Hoge2.filter(:ci_str.like 'fuga').sql<br /> => "SELECT * FROM `hoge2` WHERE (`ci_str` LIKE BINARY 'fuga')"<br /><br /># ilikeでfilter => カラムのcollationに依存
ruby-1.9.1-p378 > Hoge2.filter(:ci_str.ilike 'fuga').sql<br /> => "SELECT * FROM `hoge2` WHERE (`ci_str` LIKE 'fuga')"<br /><br /># case-sensitiveなカラムを大文字小文字無視してSELECT
ruby-1.9.1-p378 > Hoge2.filter{ |f| [f.lower(:cs_str) => 'fuga'] }.sql<br /> => "SELECT * FROM `hoge2` WHERE ((lower(`cs_str`) = 'fuga'))"
sequelを使う場合のお勧め
  • テーブル / カラムはデフォルトの照合順序(case-insensitive)にしておく
  • SQLでは大文字小文字を区別したいときBINARYキーワードでキャストを行う
  • sequelでは文字列でfilterする場合普段はlikeを使い、明示的に大文字小文字を同一視したいときだけilikeを使う

以上がダイジェスト。あとは検証過程なので興味と時間的余裕がある方はどうぞ。

(さらに…)

Sinatraで書いているwebアプリに認証機能が必要になったので「sinatra-authentication」を使ってみたメモ。

概要

Rubyでwebアプリを書くのに大人気のSinatra。でもweb開発で必要になる機能ってどんなフレームワークでもあんまり変わらないので、そのうち「認証機能が必要だよね」なんてことになる。

最初はRack::Auth::Basicを使っていたのだが、ユーザの追加 / 変更が面倒だったり、どうも挙動が不安定だったり(一定時間ログインできなくなるという謎の不具合が出たり)したので、他のライブラリを検討してみた。

自分でこんな感じのものを作ろうかなーとも思ったのだが、まずはあるものを使ってみよう、ということで「sinatra-authentication」を導入してみた。

環境

  • CentOS 5.4
  • MySQL 5.1.47
  • apache 2.2.14
  • ruby 1.9.1 p378
  • rack 1.2.1
  • passenger 2.2.14
  • sequel 3.13.0
  • ruby-mysql 2.8.1
  • sinatra 1.0
  • sinatra-authentication HEAD (0.3.2 159149)
  • rack-flash 0.1.1
  • haml 3.0.16

(さらに…)