忍者ブログ

ぢみへんプログラミング日誌

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

ヴィジュネル暗号用のgemを公開してみた。

ヴィジュネル暗号というのはその名の通り暗号処理方式の一種で、その詳しい歴史についてはwikipediaを参照してもらうとして、本日その処理をrubyで簡単に行うためのライブラリ(vigenere_cipher 1.0.0.pre)を公開した。(ソースコードはgithubから入手可能)

gemを作るのもgithubを使うのも初めてだったので結構大変だった。
そのあたりについては後日、手順等をまとめておこうと考えている。

現在の暗号技術から言ってヴィジュネル暗号自体は大したものとは言えない。
しかし鍵となるキーワードが十分に長く、暗号方式が秘密であれば、簡易的用途で用いる分には、今でもある程度使える余地はある。

要望等はgithubの方か、もしくは当ブログにてお願いします。
PR

rubygem が反応しなくなったら

仮想マシンを使っていくつもOSをインストールし、Ruby on Rails の環境を作っていると、ときたまrubygemが全く反応しなかったり、反応しても不安定になることがある。筆者が確認できた特徴は以下である。
・gem list --remote が反応しない。(ごくたまに反応することはある)
・gem install が反応しない。
なお gem install については、V オプションを付けて実行すると、現在の通信状況が分かるので便利だ。
例) gem install -V gem名
(--no-ri --no-rdoc オプションを付けるとインストール時間の節約にもなる)

gem install にVオプションを付けて実行して以下のようなエラーが出たら要注意。
Unable to resolve dependencies: 
sprockets-rails requires sprockets (~> 2.8);
railties requires thor (< 2.0, >= 0.18.1);
actionmailer requires mail (~> 2.5.4);
activerecord requires activemodel (= 4.0.1), arel (~> 4.0.0), activerecord-deprecated_finders (~> 1.0.2);
actionpack requires builder (~> 3.1.0), rack (~> 1.5.2), rack-test (~> 0.6.2), erubis (~> 2.7.0);
activesupport requires thread_safe (~> 0.1)


ERROR: Could not find a valid gem 'rails' (>= 0), here is why:
Unable to download data from https://rubygems.org/ - no such name (https://rubygems.org/latest_specs.4.8.gz)


上記2点のエラーには非常に手こずらされた。
結論から言うと、これらのエラーは大体、次の問題のどれかまたは全てに起因している。
・DNSの問題で「rubygem.org」の名前解決ができない
・SSLの問題でHTTPSアクセスを拒否されてしまっている(ように見える)
・ファイアウォールで443番ポートへの送信を拒否している

ファイアウォールに関しては確認の上、443番ポートへの外部送信を許可すればよいとして、DNSを原因とする場合は、wget コマンドを使って確認することができる。
> wget https://rubygems.org/specs.4.8.gz
--2013-11-04 13:18:16-- https://rubygems.org/specs.4.8.gz
rubygems.org をDNSに問いあわせています... 失敗しました: ホスト名に対応するアドレスがありません.
wget: ホストアドレス `rubygems.org' を解決できませんでした。


この反応が出たら、何らかの理由でDNSが名前解決をできていない可能性を疑うべきだろう。
それに加えて、SSLの問題が絡んでいる可能性もある。それについてはGitHubに掲載されている。

ではここまでに書いた状況に陥ってしまったらどうすればいいのだろう?

gemコマンドの入力を通常とは変える、というのがその答えとなる。
> nslookup rubygems.org
;; Question section mismatch: got rubygems.org/AAAA/IN
Server: 220.152.38.201
Address: 220.152.38.201#53

Non-authoritative answer:
Name: rubygems.org
Address: 54.245.255.174

> gem install -V rails --source http://54.245.255.174


まずはnslookup(またはdig)コマンドでrubygems.org のIPアドレスを特定する。
次にgem install で --source オプションを指定し、gemのダウンロード元のサーバーを特定するのだが、このときに先のIPアドレスを指定する。またプロトコルはhttps ではなく「http」とする。この対応で正常にgemをインストールできるようになるはずだ。

リモートサーバー(ダウンロード元サーバー)にあるgem の一覧を見るときもこれと同じ工夫をすれば良い。
> gem list --remote --source http://54.245.255.174



が、しかし、

まだこれで終わりではなかった……笑

恐らくこのブログを見ている人の少なくない数がRailsを使っていると思われるが、もしその人の環境で上述したようにrubygem が動かない場合、それは

bundlerも動かない

ことを意味している。
そして筆者もすぐにその穴に落ちてしまったのだった 笑
この場合、良いのか悪いのか別にして筆者の場合は/etc/hosts ファイルに直接 rubygems.org のアドレスを書くことで回避できた(ように見えるが確信はない)。
vi /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
54.245.255.174 rubygems.org

CentOS6.4 + ruby2.0 + rails4 インストール備忘録

今春rubyがバージョン2に、夏に入ってRailsも正式にバージョン4となった。
そしてまた、筆者の担当するプロジェクトでそれらの組み合わせを再度CentOS上に構築しなくてはならなくなったので、備忘録的にメモを残しておく。

メモといっても、実際には過去Rails3 をインストールしたときの教訓がそのまま使えるのでその分についてリンクのみ提示し割愛させていただく。

ruby-1.9.3-p392とrails3.2.13 を CentOS 6.4 にインストールするまで (1)
ruby-1.9.3-p392とrails3.2.13 を CentOS 6.4 にインストールするまで (2)
ruby-1.9.3-p392とrails3.2.13 を CentOS 6.4 にインストールするまで (その後)

今回さらに引っかかったのは、rails server とコマンドを打ったところで、以下のエラーが出た点だった。
「/usr/local/lib/ruby/gems/2.0.0/gems/execjs-2.0.2/lib/execjs/runtimes.rb:51:in `autodetect': Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)」

どうやら execjs というモジュールが使うはずのランタイムとやらがないらしい。
そこで参照しろと指示してあるページ(https://github.com/sstephenson/execjs)に行くと、そのランタイムとはJavascript ランタイムのことであるらしいことが分かる。Rails の機能として、そうしたランタイムを使う機能がデフォルトで追加された……と考えておこう。(前回同じことで引っかかった覚えがないため、いつからそうなっているのか不明)

いくつかランタイムの候補が挙げられているのだが、筆者はnode.js を選んだ。
http://nodejs.org/

こちらでソースをダウンロード、ビルドしてから再度 rails server を実行した。

> cd /tmp
> wget http://nodejs.org/dist/v0.10.21/node-v0.10.21.tar.gz
> cd node-v0.10.21
> ./configure
> make
> make install
> cd <railsアプリのルートディレクトリ>
> rails server
=> Booting WEBrick
=> Rails 4.0.0 application starting in development on http://0.0.0.0:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
[2013-10-23 02:10:36] INFO WEBrick 1.3.1
[2013-10-23 02:10:36] INFO ruby 2.0.0 (2013-06-27) [x86_64-linux]
[2013-10-23 02:10:36] INFO WEBrick::HTTPServer#start: pid=25526 port=3000

どうやらうまくいったっぽい。

※注:node.js のコンパイルにはgccだけでなく、g++(gcc のC++バージョン)も必要

Enumerator がなんで必要なのかようやく分かった(2)

以前のエントリ「Enumerator がなんで必要なのかようやく分かった」でEnumratorクラスの存在意義について書いたが、少し補足をば。
以前の内容では本来enumerableモジュールをincludeしていないクラスでも、その代替となるメソッドを指定し、eachメソッドを持つかのように見せかけるラッパークラスとしてEnumerator の存在意義を紹介した。
irbを使って具体的に示すと以下のようになる。

irb(main):036:0> class Abc
irb(main):037:1> def initialize
irb(main):038:2> @arr = [1,2,3,4,5,6]
irb(main):039:2> end
irb(main):040:1>
irb(main):041:1* def my_each
irb(main):042:2> @arr.each{|n| yield n}
irb(main):043:2> end
irb(main):044:1> end
=> nil
irb(main):045:0>
irb(main):046:0* abc = Abc.new
=> #
irb(main):047:0> enum = Enumerator.new(abc, :my_each)
=> #:my_each>
irb(main):048:0> sum = enum.inject(0, :+)
=> 21


見ての通り、クラスAbcはenumerable をinclude してないが、my_eachメソッドを指定してEnumerator オブジェクトを生成すると、そのEnumeratorオブジェクトを通じてmapやinject等の、enumerableモジュールをinclude しなければ使えないメソッドが使えるようになる。
ここまでが以前のエントリ内容であった。

しかし現在、Object#to_enum, Object#enum_for というメソッドの存在により(enum_for はto_enum の別名メソッドで機能は同じ)、直接Enumeratorをnewメソッドで呼び出すことは滅多にない、と「プログラミング言語Ruby」(David Flanagan/まつもとゆきひろ著)には記されている。
「プログラミング言語Ruby」の「5.3.4 Enumerator」の章ではこれらのメソッドを引数無しで呼び出すと、呼び出し主体であるオブジェクトのeachメソッドを呼び出すだけのeachメソッドを持ったEnumeratorオブジェクトを返す。つまり a.to_enum と記述すると、Enumerator.new(a, :each) を実行するということだ。Object#to_enum に引数をつけると、Enumerator.new の第二引数の部分に任意のメソッド名を指定できる。その場合、to_enum よりも enum_for を使う方が名前として適しているかもしれないとも記されている。

実際にやってみるとこういうことだ。

irb(main):049:0> enum = "1234".enum_for(:each_char)
=> #<Enumerator: "1234":each_char>
irb(main):050:0> enum.map{|c| c.to_i * 2}
=> [2, 4, 6, 8]



さらにRuby 1.9からは、引数無で呼び出された場合にEnumeratorオブジェクトを返すイテレータメソッド(あるいはイテレータ的なメソッド)が増えた。特にEnumerableモジュールをミックスインした場合、each, map 等は引数無しだと全てEnumeratorオブジェクトを返す。そうした場合では、to_numもenum_for も記述不要となる場合も多くなった。

irb(main):051:0> "1234".each_char.select{|c| c.to_i.even?}
=> ["2", "4"]


これはまぁ、便利っちゃー便利な機能だと思う。

ActiveRecordのヴァリデーションを自動化する

ActiveRecord(以下ARと略)にはデータの整合性をチェックするためのヴァリデーションメソッドが用意されているんだが、たくさんのARを扱うWEBアプリを作ろうとすると、個々のARにいちいちテーブルのカラム制約に合せたヴァリデーションを記述するのが面倒くさくなってくる。
そもそもARは対応するテーブルのメタ情報は全て持っているので、それを利用してヴァリデーションを自動記述してしまった方がはっきり言って楽だろう。

――ということで作ってみました。
module AutoValidates
def self.included(klass)
klass.class_eval{
klass.columns.each do |column|
next if ["id"].include?(column.name)
if [:integer].include?(column.type) && !column.array
# 数値型確認
validates column.name.to_sym,
numericality: {unless: Proc.new{|k| eval("k.#{column.name}").nil?},
only_integer: true
elsif column.null == false
# NOT NULL
validates column.name.to_sym,
presence: {if: Proc.new{|k| eval("k.#{column.name}").nil?}
end
end
}
end
end



これをAR側でincludeすればOK.(のはず)

  

カレンダー

04 2024/05 06
S M T W T F S
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

フリーエリア

最新CM

バーコード

ブログ内検索

Copyright ©  -- ぢみへんプログラミング日誌 --  All Rights Reserved

Design by CriCri / Material by petit sozai emi / powered by NINJA TOOLS / 忍者ブログ / [PR]