Home > Programming
Programming Archive
RSpecでMacro?を書く。
- 2010-01-08 (Fri)
- Ruby
RSpecを使ってSpecを書いていると何度も同じことを書くことが多いです。
たとえばパラメータに応じてページタイトルを変えたい場合とか、validationがきちんと行われているかとか。。。
毎回、 it “should have hoge” do … end と書いているのは大変です。
RSpecではいくつかの方法を使用して、もっと簡単に書くことができます。
クラスメソッドを使う
一つのspecファイルで何度も使うものであればクラスメソッドにします。
[$RAILS_ROOT/spec/views/articles/index.html.erb_spec.rb]
describe "/articles" do
def self.it_should_have_tag(selector, content)
it "should have '#{content}' at '#{selector}'" do
response.should(have_tag(selector, content))
end
end
end
と書いておけば、以下のような書き方が可能になります。
[$RAILS_ROOT/spec/views/articles/index.html.erb_spec.rb]
describe "/articles" do
def self.it_should_have_tag(selector, content)
it "should have '#{content}' at '#{selector}'" do
response.should(have_tag(selector, content))
end
end
it_should_have_tag('tr>td', 'MyString')
end
it_should_have_tag(’tr>td’, ‘MyString’) の部分だけで適切なspecに展開されます。
1行で簡潔に書けますので、理解する時間も短くてすみます。
自分はページタイトル、meta description、meta keywords、RSSのスペックに以下のコードを使用しています。
[$RAILS_ROOT/spec/views/articles/index.html.erb_spec.rb]
describe "/articles" do
def self.it_should_have_tag(selector, content)
it "should have '#{content}' at '#{selector}'" do
response.should(have_tag(selector, content))
end
end
def self.it_should_have_page_title(title)
it_should_have_tag('head>title', title)
end
def self.it_should_have_meta_description(meta_description)
it_should_have_tag('head>meta[name=description][content=?]', meta_description)
end
def self.it_should_have_meta_keywords(meta_keywords)
it_should_have_tag('head>meta[name=keywords][content=?]', meta_keywords)
end
def self.it_should_have_rss_link(link)
it_should_have_tag('head>link[rel=alternate][type=application/rss+xml][href=?]', link)
end
end
モジュールに追い出す
さらによく使う項目、上記のhtmlに関するspecなどはたくさんのところに書かれるであろうことが推測されます。
そういう場合には、モジュールに追い出してしまうということが可能だということを同僚のquekさんに教えていただきました。1
$RAILS_ROOT/spec/support フォルダにモジュールのファイルを書きます。
上記の例であれば
[$RAILS_ROOT/spec/support/tag_macros.rb]
module TagMacros
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def it_should_have_tag(selector, content)
it "should have '#{content}' at '#{selector}'" do
response.should(have_tag(selector, content))
end
end
def it_should_have_page_title(title)
it_should_have_tag('head>title', title)
end
def it_should_have_meta_description(meta_description)
it_should_have_tag('head>meta[name=description][content=?]', meta_description)
end
def it_should_have_meta_keywords(meta_keywords)
it_should_have_tag('head>meta[name=keywords][content=?]', meta_keywords)
end
def it_should_have_rss_link(link)
it_should_have_tag('head>link[rel=alternate][type=application/rss+xml][href=?]', link)
end
end
end
使用する際には include TagMacros を書いておきます。
[$RAILS_ROOT/spec/views/articles/index.html.erb_spec.rb]
describe "/articles" do
include TagMacros
it_should_have_tag('tr>td', 'MyString')
end
自分のような include 〜 を書くのもものぐさだという人は、 $RAILS_ROOT/spec/spec_helper.rb に config.include メソッドを使用すれば、自動的に読み込まれるようになります。
[$RAILS_ROOT/spec/spec_helper.rb]
Spec::Runner.configure do |config| # ... config.include(TagMacros, :type => [:views]) # ... end
上記のように :type を指定すれば view だけで読み込まれるというような指定も可能です。
参考
Railscasts – RSpec Matchers & Macros
Writing Macros in RSpec • Blog Archive • Ben Mabey
P.S.
参考にしたサイトではMacroと書いてありますが、どうもこれをMacroと読んでいいものなのかどうかかなり謎なので、タイトルはMacro?と?付きにしてみましたwww
- quekさんによると、下の「参考」のところに書いた Railscasts に同様のことが書いてあり、そのアドレスを過去の自分は社内のチケットに書いていたらしいのですが、モジュールに出すことは全く知りませんでしたwww [↩]
- Comments: 0
- Trackbacks: 0
Grand Central Dispatchを試してみる。
- 2009-09-02 (Wed)
- Programming
Snow LeopardではOSの基礎部分にかなりの改良を加えたと、Appleはいいます。
その基礎部分の改良の目玉機能の一つであるGrand Central Dispatchは、マルチコアでのプログラミングを簡単に行うためのフレームワークを提供してくれます。
マルチコアでのプログラミングはいろいろと難しいことが多く自分は興味を持ったので、プログラムプレゼンテーションのネタに少し試してみることにしました。
すでに最初の一歩を踏み出された方がいます。
Grand Central Dispatch at mootoh.log
Grand Central Dispatch をためす at mootoh.log
Grand Central Dispatchを試してみる – 理想未来はどうなった?
dispatch_asyncというのは非同期に与えたブロックを実行するもので、
対してdispatch_syncというものは同期的にブロックを実行するものようです。
この同期、非同期というものを自分はきちんと理解していないのですが、Concurrency Programming Guildeというドキュメントによると。。。
- dispatch_async
-
Submits a block for asynchronous execution on a dispatch queue and returns immediately.
- dispatch_sync
-
Submits a block object for execution on a dispatch queue and waits synchronously until that block completes.
- 引用元: Grand Central Dispatch (GCD) Reference
dispatch_syncはブロックが終了するまで待ってるよという風に見えます。
上記のサンプルを参考にしつつ、ためしにこんなコードを書いてみました。
#include <dispatch/dispatch.h>
#include <iostream>
#include <stdio.h>
#include <unistd.h>
void c_hello(int count = 10)
{
void (^hello)(int) = ^(int x)
{
printf("Hello, C World! %d\n", x);
};
for (int i = 0; i < count; ++i)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
hello(i);
});
}
}
void cpp_hello(int count = 10)
{
void (^hello)(int) = ^(int x)
{
std::cout << "Hello, C++ World! " << x << std::endl;
};
for (int i = 0; i < count; ++i)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
hello(i);
});
}
}
int main (int argc, char * const argv[])
{
c_hello(1000);
cpp_hello(1000);
std::cout << "done!" << std::endl;
// sleep がないと処理が終了する前に return してしまう。
sleep(5);
return 0;
}
カリー化はブロックをブロックでくくればいいのでしょうか?
わざとCのprintfとC++のstd::coutの両方を書いてみました。
面白かったのが1000回ループをさせたときでした。
10回では起こりませんでしたが、回数が増えるにつれ、C++の方はこんな風にごちゃ混ぜになりました。
Hello, C++ World! Hello, C++ World! Hello, C++ World! 974975976977978
ちょっと考えてみると、<< 演算子で何個ものメソッドが入り組んでいる分、多数のスレッドが起動されるとこうなるのでしょう。
実際にプログラムプレゼンテーションで見せて、なにか簡単ないいサンプルがないと話してみたところ、g000001さんに疑似並行処理 どう書く?orgという課題をやってみてはどうか?というアドバイスをいただきました。
これがその解答になるかと思います。
#include <dispatch/dispatch.h>
#include <stdio.h>
#include <unistd.h>
int main (int argc, char * const argv[])
{
void (^alphabet)(int x) = ^(int x)
{
putchar('a' + x);
putchar(' ');
};
void (^number)(int x) = ^(int x)
{
printf("%d ", x);
};
for (int i = 0; i < 26; ++i)
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{ alphabet(i); });
dispatch_async(queue, ^{ number(i); });
}
printf("done!\n");
sleep(5);
return 0;
}
結果は次のようになって、アルファベットと数字が無事混ざって表示されました。
done! a 0 b 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 k 10 l 11 m 12 n 13 o 14 p 15 q 16 r 17 s 18 t 19 u 20 v 21 w 22 x 23 y 24 z 25
これからは共有リソースをどうやって扱うことができるのか調べたいところです。
P.S.
スレッド関連の用語を知らないので、適当に書いたところが多々あります。
うまく説明できないのが非常にもどかしいところです。
- Comments: 0
- Trackbacks: 0
ssl_requirement pluginでssl_required(:all)と書きたい!
- 2009-08-27 (Thu)
- Ruby
Ruby on RailsでSSLで通信する必要があるページには、DHH謹製らしい?ssl_requirement pluginを使用すると、以下のようにに簡単にhttpsにリダイレクトしてくれるようにできます。
class Hoge < ApplicationController
ssl_required(:index) # インデックスページだけSSLで通信する。
def index
# some crazy codes ...
end
def show
# some rotten codes ...
end
end
残念ながら、このssl_requiredはアクションに:allとか書いてコントローラ全部を対象にするというようなことができません。
allというアクションを定義する場合もあるからこうなっているのかもしれません。
コントローラ全体にSSL通信をさせるようにするための方法については、コントローラ全体をssl強制に – 車輪の再発明というサイトに、trueを返すssl_required?メソッドを定義する方法が書かれています。
現在書いているRailsアプリでも同様のことが行われているものの、いかんせんたびたび見る気がしてきて、クラスメソッドにしようかと思いました。
でも、すでにssl_requiredというメソッドがあるところに、さらなる同じようなメソッドを作るのは避けたいし、やっぱりssl_required(:all)と書きたいと思いました。
そこでalias_method_chainを使用して、ApplicationControllerをこんな風にしてみました。
class ApplicationController < ActionController::Base
include SslRequirement
# some codes...
class << self
def ssl_required_with_all(*actions)
if actions.include?(:all)
class_eval do
def ssl_required?
true
end
end
else
class_eval do
ssl_required_without_all(*actions)
end
end
end
alias_method_chain(:ssl_required, :all)
end
end
まともにclass_evalとかがわかっていないので、かなり怪しいです!!!
- Comments: 0
- Trackbacks: 0
Apple Push Notification Serviceを利用した、iPhone クライアントと、Rubyによるサーバの作成。
[とりあえず表示しましたが、これからコードをアップロードしたり改変していきます。]
先週から、システム部で何か動くものを作って発表するという企画?が始まりました。
プログラムプレゼンテーションを始めてみたら意外に良かった
第一弾は自分だったので、1週間しかなかったので、ちょこっとやればできそうで今までやってみたかったiPhone OS 3.0の目玉機能の一つ、Push Notification Serviceの実装をやってみることにしてみました。
iPhoneクライアントはほぼObjective-Cしかありませんのでそれを使い、サーバはRubyで実装しました。
以下が発表したスライドを少し改変したものになります。
コードは今回はbitbucket.orgにアップロードすることにしました!
コードはこちらになります。
http://bitbucket.org/milkcocoa/apns-test/
ただしサーバのファイルに関しては
- デバイスIDとかの部分はxでマスクしています。
- キーに関してはスライドで指定した方法で記述してください。
[ポイントを書く。]
- Comments: 0
- Trackbacks: 2
mislav-will_paginate pluginを使用したページをRSpecでテストする。
- 2009-07-19 (Sun)
- Ruby
Webアプリケーションでは、たくさんの項目を一覧表示する場合、1ページに全部見せるのではなくpaginate処理をして数ページに分ける場合があります。
たとえばGoogleの検索結果は通常、1ページに10件しか表示されません。
そういうページをRuby on Railsで作成する場合には、mislav-will_paginate pluginというプラグインを使用するということは割とよく知られていることです。
先日もそういうページを作成する必要があり、作成していましたが、RSpecでテストを作成しようとしたところやり方がわからず詰まりました。
そのため、その方法をここに記しておこうと思います。
ドキュメントを読もう!
実はGitHubのpluginのWikiページに最低限必要なことは書いてありました。
気がついていればもっと早く解決していたところでした。
「I’m getting “undefined method `total_pages’” error when rendering in the view!」という部分ですね。
ポイントはpaginateやtotal_pagesというメソッドをstub!で定義してあげることです。
実際のコード
- Controller: ArticlesController
- Model: Article
- title: string
- body: text
Controllerのテスト(の一部)
[$RAILS_ROOT/spec/controllers/articles_controller_spec.rb]
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe ArticlesController do
describe "handling GET /articles" do
before(:each) do
article = mock_model(Article)
article.stub!(:find).and_return([article])
@articles = [article]
@articles.stub!(:total_pages).and_return(1)
@articles.stub!(:paginate).and_return(@articles)
end
def do_get
get(:index)
end
it "should be successful" do
do_get
response.should be_success
end
it "should render index template" do
do_get
response.should render_template('index')
end
it "should find all articles" do
Article.should_receive(:paginate).with(:page => nil, :per_page => 100).and_return(@articles)
do_get
end
it "should assign the found articles for the view" do
do_get
assigns[:articles].should == @articles
end
end
end
ちなみに29行目の:page => nilになっているのは、たぶんassingsとかでparameterを指定していないからこうなるのだと思います。
まだshould_receiveをきちんと理解していないで、まともな説明が書けません。
Viewのテスト(の一部)
[$RAILS_ROOT/spec/views/articles/index.html.erb_spec.rb]
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
describe "/articles/index.html.erb" do
include ArticlesHelper
before(:each) do
article_98 = mock_model(Article)
article_98.stub!(:id).and_return(1)
article_98.stub!(:title).and_return('MyString')
article_98.stub!(:body).and_return('MyText')
article_99 = mock_model(Article)
article_99.stub!(:id).and_return(2)
article_99.stub!(:title).and_return('MyString')
article_99.stub!(:body).and_return('MyText')
@articles = [article_98, article_99]
@articles.stub!(:total_pages).and_return(1)
@articles.stub!(:paginate).and_return(@articles)
assigns[:articles] = @articles
end
it "should render list of articles" do
render "/articles/index.html.erb"
response.should have_tag("tr>td", "MyString", 2)
response.should have_tag("tr>td", "MyText", 2)
end
end
- Comments: 0
- Trackbacks: 0
RubyでArrayの部分集合を作成する。
- 2009-07-10 (Fri)
- Ruby
Arrayの部分集合を作成する必要があったので、作ってみました。
class Array
def subset
rec = Proc.new do |univ|
# subset!でポインタが循環しないようにcloneを使う。
(ret = []) << univ.clone
univ.each do |e|
ret += rec.call(univ - [e])
end
ret
end
rec.call(self).uniq
end
def subset!
self.replace(self.subset)
end
end
他には同じサイズの配列を作成して、その要素を使用するかどうかtrueかfalseのフラグを立てていくという手法もあるようです。
irbで実行するとこうなります。
>> a = %w(1 2 3 4) => ["1", "2", "3", "4"] >> a.subset => [["1", "2", "3", "4"], ["2", "3", "4"], ["3", "4"], ["4"], [], ["3"], ["2", "4"], ["2"], ["2", "3"], ["1", "3", "4"], ["1", "4"], ["1"], ["1", "3"], ["1", "2", "4"], ["1", "2"], ["1", "2", "3"]]
2009/7/20 追記
twitterですばらしい方法を教えていただきました!
ただしRuby 1.8.7で追加されたcombinationというメソッドを使用しているので1.8.7以降限定です。
cf. Ruby 1.8.7で使えるようになったRuby 1.9のメソッドたち – (rubikitch loves (Emacs Ruby CUI))
class Array
def subset
(0..self.length).inject([]) do |ret, n|
ret.push(*self.combination(n))
end
end
end
irbでの実行結果。
>> a = %w(1 2 3 4) => ["1", "2", "3", "4"] >> a.subset => [[], ["1"], ["2"], ["3"], ["4"], ["1", "2"], ["1", "3"], ["1", "4"], ["2", "3"], ["2", "4"], ["3", "4"], ["1", "2", "3"], ["1", "2", "4"], ["1", "3", "4"], ["2", "3", "4"], ["1", "2", "3", "4"]]
すごくすっきりしました!
- Comments: 0
- Trackbacks: 0
レセプトオンライン送信で請求ができたかを確認するRubyスクリプト
- 2009-05-08 (Fri)
- Pharmaceutical sciences | Ruby
すごいニッチなところをすみませんwww。
レセプトオンライン送信について知っている人だけをまずは対象にしています。
複数の店舗のレセプトを一括してオンライン請求するときにきちんと請求済みになっているかどうか1 を(念のため)確認するのは2(社保、国保) × 店舗数分やらないといけないので大変です。
特にEeePCを使っていると遅いので、だいぶん大変度が増します。
ということで、Rubyでオートマティックに確認するスクリプトを書いてみました。
神奈川県の事例しか知らないので神奈川県限定です。
スクリプト中の神奈川県に関する部分を修正すれば、ほかの県でももしかしたら利用できるかもしれません。
またHTMLを解析して、やっていますのでサイトの構成やHTML等が変わってしまった場合には利用ができません。
共有はしますが、ノーサポートです。
私はこのスクリプトを使用して生じた一切の責任を負いません。
ライセンスをどうしようかと思いましたが、どのみちスクリプトですから改変しても公開せざるを得ないと思うので、GPLv3にしておきます。2
動作環境は
- Windows3
- Ruby 1.8.7
- RubyGems 1.3.2
RubyGemsによってインストールした- WWW::Mechanize 0.9.2
- Term::ANSIColor 1.0.3
- Win32Console 1.2.0
- およびそれらの依存ライブラリ(Nokogiri等)
です。
これらのインストールに関する質問はお答えできませんので、あらかじめご了承を。
さらにopenssl(UNIX系だと普通にあると思われる4 )を用いて配布されているp12形式の証明書ファイルからcerファイルとkeyファイル(この二つをいまいちわかっていない)を作成します。
パスワードの入力を求められますが、これは証明書発行時に発行されたパスワードになります。
openssl pkcs12 -in hoge.p12 -clcerts -out hoge.cer -nokeys openssl pkcs12 -in hoge.p12 -clcerts -out hoge.key -nocerts -nodes
さらに店舗情報としてYAMLファイルを作成します。
名前は適当につけていただいて、ファイルの中身は
- name: hoge id: 0120444444 password: hogepass cert: hoge.cer key: hoge.key - name: piyo id: 0120888888 password: piyopass cert: piyo.cer key: piyo.key
とかしてください。
nameは任意の区別できる名前にします。
id, passwordはその薬局がログインするときのIDとパスワードです。
certとkeyは上記で作成したcertファイルとkeyファイルのパスを指定します。
後のオプションはきっとわかると思います。
このときWindowsでパス区切りに使われるバックスラッシュ(\)はうまく動いてくれなかったように思えるので、スラッシュでパスを区切りました。
あとは
ruby receipt_check.rb hoge.yaml
とでも打ち込めば、請求済みであれば緑色の字で[OK]、請求済みになっていない場合には[Failed]と表示されます。
ruby receipt_check.rb -t hoge.yaml
のように -t オプションをつけると、確認試験で実行します。
さらに自分は上記コマンドを呼び出すバッチファイルを作成し、それをcmd.exeで呼び出すリンクファイルを作ってリンクファイルをクリックするだけで確認できるようにしてあります。
TODOはそこにも書いてありますが、エラー処理を全くしていません。
そのため運用時間外などに実行すると、運用時間外ですとか知らせることなく、思い切りスクリプトのエラーが出ます。
もしやる気があれば、未請求になっていた場合にはスクリプトで請求できるようにしたり、もうスクリプトだけで請求するということも考えています(こちらは実現が難しそう)。
あと、できるだけ修正はしたいと思いますが、最終的なデバッグはレセプトオンライン送信の端末でしかできないので、修正まで非常に時間がかかる場合、修正しない場合があります。
ということで、以上を理解した方のみダウンロードはこちらから。
- Comments: 0
- Trackbacks: 0
Xcodeで0xE8000001エラー(iPhone OS 2.2.1)
iPhone OS 2.2.1をインストールしたiPhoneにXcodeで作成したプログラムを転送しようとすると、
Your mobile device has encountered an unexpected error (0xE8000001)
Try disconnecting and powering off the device; then power the device on and reconnect it.
などというエラーが発生し、XcodeがiPhoneを認識しないという状況に陥ります。
これの解決策は
/var/mobile/Media/PublicStaging
を削除し(jailbreakする必要があります)、再起動することです。
なぜ発生するのかは、今の自分にはよくわかりません(jailbreakしたから???)。
- Comments: 0
- Trackbacks: 0
WP-Analog: IE6で閲覧すると右上に「アナログ」と表示されるWordPressプラグイン 〜 初めてのWordPressプラグイン作り
- 2009-01-05 (Mon)
- Programming | WordPress
ネタが古い感がありますが、Internet Explorer 6だと右上に「アナログ」という画像が表示されるようにしてあります。
当サイトではこのように表示されます。1
この画像はIE NetRenderer – Browser Compatibility Check -を使って取得しました。
ネタ元はIE6で閲覧すると。|CSS HappyLifeです。
CSS Happy Lifeで発表後Javascriptを使用して、埋め込むようにするものも登場しました。
IE6でアクセスしたらページ右上に「アナログ」と表示するJavaScript – The blog of H.Fujimoto
今までWordPressのプラグインを作ったことがなく、 せっかくなので上記のJavascriptを利用して、学習がてらWordPressのプラグインにしてしまうことにしました。
WordPressのプラグイン作り
WordPressのプラグインを作るに当たり、元々付属しているhello.phpを参考にしました。
WordPressのプラグインはおろか、PHPのコーディングをするのが初めてだったので、たった数行だったのに色々とはまりました:-P2
1. プラグイン作りの準備
まず最初にanalogDisp.jsをフォルダに入れます。
今回は、/wp-content/plugins/wp-analogというフォルダに入れました。
2. PHPのコードの記述
WordPressのプラグイン作りのポイントは、アクションとフィルタです。
SPaiS – Wordpress プラグインの作り方(1)というサイトに詳しく記されています。
この場合、必要なのはブログのヘッダにJavascriptを指し示す、scriptタグを埋め込むことです。
つまり、WordPressがヘッダを作成する際に、scriptタグを埋め込む関数を実行すればよいということになります。
ということで、add_actionを以下のように使用する訳です。
<?php
/*
Plugin Name: WP-Analog
Plugin URI: http://www.cocoalife.net/wp-analog/
Description: This is the WordPress plugin which shows "アナログ" when a browser is IE 6.
Author: milkcocoa
Version: 1.0
Author URI: http://www.cocoalife.net/
*/
function add_analog_js() {
echo("\t<script type=\"text/javascript\" src=\"" . get_bloginfo('wpurl') . "/wp-content/plugins/wp-analog/analogDisp.js" . "\"></script>\n");
}
add_action('wp_head', 'add_analog_js');
?>
これで、ヘッダが作成される際に、add_analog_js()という関数が呼び出されるようになります。
add_analog_js()関数ではechoを使って、scriptタグを埋め込みをしています。
get_bloginfo(’wpurl’)でWordPressのSettings – General - WordPress address (URL)という項目で指定されるWordPressのURLを取得しています。
さらに、”.”を用いて文字列を連結しています。
一つはまった?(というほどでもないけれど)のはPHPの言語仕様で、Rubyと同様に一重引用符ではタブ文字を表す\tなどのバックスラッシュ記法が展開されないということです。
ですので、二重引用符を使用します。
さて、これをwp-analog.phpとでもして保存し、先ほどのフォルダにアップロードしましょう。
そしてアクティベートすれば終了です。
と、かなり丁寧にWordPressのプラグインとPHPについて説明しました(つもりです)。
- Comments: 0
- Trackbacks: 1
Ultraviolet Syntax Highlighting Engineをさくらインターネットのサーバにインストールする
- 2009-01-04 (Sun)
- Programming | Ruby | UN*X | Web
UltravioletはRubyによって書かれた様々なSyntax(文法)に対応したSyntax Highlighting Engineです。
今回はこれをさくらインターネットのサーバにインストールしてみましょう。
RubyGemsを使ってインストールをするのですが、以前RubyGemsのインストール方法については書きました。
cocoa*life – ブログをさくらインターネットへ移行しました。
ということで、RubyGemsのインストールが終わっている状態で書き始めます。
Ultravioletのインストール
正規表現ライブラリOniguruma(鬼車)のインストール
まずは正規表現ライブラリであるOnigurumaをインストールします。
普通にconfigureしてmakeしてinstallすれば良いだけです。
wget http://www.geocities.jp/kosako3/oniguruma/archive/onig-5.9.1.tar.gz tar zxf onig-5.9.1.tar.gz cd onig-5.9.1 ./configure --prefix=$HOME/local make make install
RubyGemsを使ってUltravioletのインストール
一直線に答えを書いてしまってもいいのですが、問題解決法を書くのも忘れてしまう自分のためになると思うので、書きます。
gem install -r ultraviolet
とすればいいと思いきや、こんなエラーが出て止まります。
oregexp.c:2:23: oniguruma.h: No such file or directory
どうも標準ではない/home/hoge/local/以下にインストールしてあるので、oniguruma.hなどが見つからないようです。
さらに、エラーの最後を見ていると
Stop in /home/hoge/local/gems/oniguruma-1.1.0/ext.
なんて書いてあって、 どうも依存関係によりまず他のライブラリをインストールしているよう。
調べてみるとOniguruma for Rubyというものらしい。
そこでまず~/local/gems/oniguruma-1.1.0というフォルダを見てみると、Rakefileがある。
さらに中身を読んでみると、30 〜 36行目に以下のような記述があります。
if ENV['PLATFORM'] =~ /win32/ p.lib_files = ["win/oregexp.so"] p.spec_extras[:require_paths] = ["win", "lib", "ext" ] p.spec_extras[:platform] = Gem::Platform::WIN32 else p.spec_extras[:extensions] = ["ext/extconf.rb"] end
どうも、ext/extconf.rbがくさそうだという気がしたので、ext/extconf.rbを見てみます。
require 'mkmf'
have_library("onig")
$CFLAGS='-Wall'
create_makefile( "oregexp" )
たった4行!
ですがcreate_makefileでMakefileを作成しているというのは読み取れますので、何かありそうです。
そしてどうも、require ’mkmf’というのが鍵を握っている様な気がしました。
mkmf – Rubyリファレンスマニュアル
Ruby の拡張ライブラリのための Makefile を作成するライブラリです。
ということで、ビンゴでしょうか?
さらに読み進めると
- –with-opt-dir=directory
- ヘッダファイル、ライブラリファイルを探索するディレクトリ directory/include、directory/lib をそれぞれ追加します。
と書いてあるので、これを指定できればいいということになります。
ということで、
gem install -r oniguruma -- --with-opt-dir=$HOME/local gem install -r ultraviolet
として、これでめでたくインストールが完了します。1
RubyGemsに慣れている人であれば当たり前のことなのかもしれませんが、自分は初めてだったので良い経験になりました。
Ultravioletの使い方
uvというコマンドがUltravioletのコマンドになりますが、uv –helpでヘルプを見てみると
uv -t amy -h ~/.bashrc > bashrc.html
なんてのがサンプルとして書いてあります。
amyというのはテーマの名前のようです。
テーマはUltraviolet Theme Galleryで見ることができます。
-sでSyntaxを指定することができますが、ある程度は自動的に認識されるのかもしれません。
uv -l syntax
で利用可能なSyntax一覧を表示することが可能です。
自分は.zshrcをやってみました。
Syntaxが認識されないので、-s shell-unix-genericというのを指定しました。
uv -t blackboard -s shell-unix-generic -h ~/.zshrc > zshrc.html
生成されたzshrc.htmlはcssを参照しているところがあるのですが、そのcssは
/home/hoge/local/gems/ultraviolet-0.10.2/render/xhtml/files/cssにあります。
Rubyからもライブラリとして使うことができるようです。
Usageのところを見ると書いてあります。
- 試してはいないけれど、gem install -r ultraviolet — –with-opt-dir=$HOME/localでうまくいくのかなぁ? [↩]
- Comments: 0
- Trackbacks: 0
Home > Programming



