<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ruby | FreeStyleVision</title>
	<atom:link href="https://freestyle.nvo.jp/archives/tag/ruby/feed" rel="self" type="application/rss+xml" />
	<link>https://freestyle.nvo.jp</link>
	<description>ネクストビジョン社員による情報配信を行っているブログです。</description>
	<lastBuildDate>Sat, 14 May 2016 14:06:13 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.4</generator>

<image>
	<url>https://freestyle.nvo.jp/__wp__/wp-content/uploads/2025/10/cropped-FSV_icon-32x32.png</url>
	<title>Ruby | FreeStyleVision</title>
	<link>https://freestyle.nvo.jp</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>いまさらRakeについての覚書</title>
		<link>https://freestyle.nvo.jp/archives/1913?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e3%2581%2584%25e3%2581%25be%25e3%2581%2595%25e3%2582%2589rake%25e3%2581%25ab%25e3%2581%25a4%25e3%2581%2584%25e3%2581%25a6%25e3%2581%25ae%25e8%25a6%259a%25e6%259b%25b8</link>
		
		<dc:creator><![CDATA[山平]]></dc:creator>
		<pubDate>Sat, 14 May 2016 14:06:13 +0000</pubDate>
				<category><![CDATA[技術情報]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[ツール]]></category>
		<guid isPermaLink="false">http://freestyle.nvo.jp/?p=1913</guid>

					<description><![CDATA[<p>タイトルそのままですが、最近Rakeを使ってみて、勘所を残しておきたいと思います。 Rake とは Rake は Make によく似た機能を持つ Ruby で書かれたシンプルなビルドツールです。 Rake は以下のような [&#8230;]</p>
<p>The post <a href="https://freestyle.nvo.jp/archives/1913">いまさらRakeについての覚書</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>タイトルそのままですが、最近Rakeを使ってみて、勘所を残しておきたいと思います。</p>
<blockquote><p>Rake とは<br />
Rake は Make によく似た機能を持つ Ruby で書かれたシンプルなビルドツールです。<br />
Rake は以下のような特徴を持っています。</p>
<ul>
<li>Rakefile (Rake における Makefile) は標準的な Ruby の文法で書くことができます。 XML ファイルを編集する必要はありませんし、Makefile の風変わりな文法 (タブだっけ？スペースだっけ？) に頭を悩ませる必要もありません。</li>
<li>ユーザは必須条件をタスクに指定できます。</li>
<li>Rake は暗黙のタスクを合成することをサポートしています。</li>
<li>配列のように振る舞うフレキシブルな FileList メソッドがあります。 FileList はファイル名やパス名を扱うのに便利です。</li>
<li>Rakefile をより簡単に作成するためにこのライブラリにはいくつかのタスクが同梱されています。</li>
</ul>
<p><a rel="noopener" target="_blank" href="http://docs.ruby-lang.org/ja/2.2.0/library/rake.html">library rake (Ruby 2.2.0)<span class="fa fa-external-link external-icon anchor-icon"></span></a>より引用</p></blockquote>
<p><span id="more-1913"></span></p>
<p>Rakeの使い方に関しては、検索するとたくさん出てきますので、そちらを参照していただければよいかと思います。</p>
<ul>
<li><a rel="noopener" target="_blank" href="http://www2s.biglobe.ne.jp/~idesaku/sss/tech/rake/">Rake<span class="fa fa-external-link external-icon anchor-icon"></span></a></li>
<li><a rel="noopener" target="_blank" href="http://unageanu.hatenablog.com/entry/20100829/1283069269">Rakeの基本的な使い方まとめ &#8211; うなの日記<span class="fa fa-external-link external-icon anchor-icon"></span></a></li>
</ul>
<p>Rakeの最大の特徴はRubyのDSLとして実装されている点です。</p>
<p>Rakefileもタスク記述用の機能が追加されたrubyプログラムなので、タスクの定義が即動作するコードだということです。<br />
Javaまわりだと、定義はxmlなことが多いので、動かすにはもうひと手間かかります。</p>
<p>つまりこれって、タスクのインターフェイスとして使えるということです。</p>
<p>GitHubが採用しているJekyllをブログ寄りにお膳立てしてくれているoctopressというツールがまさにこれでして、rekeのタスクの中でjekyllコマンドをたたいています。</p>
<p>要はこんな感じです。</p>
<ul>
<li>コマンドラインアプリケーションのIFをタスクとして公開する<br />
タスクのリストや説明の表示もrakeオプションで提供されている</li>
<li>コマンドラインアプリケーションの依存関係は勝手に解決してくれる<br />
日次⇒週次⇒月次など、先に実行する必要がある処理は依存関係として登録できる</li>
<li>rubyのプログラムなので、IF提供しない機能はタスク定義しなければよい<br />
具体的な機能は通常の関数定義で定義すればよいだけ</li>
</ul>
<p>と、使い方によってはとても便利なrakeですが、バージョンの関係か、2つ以上の引数を渡す部分で、ネットの情報通りでは動かないことがありました。</p>
<ul>
<li><a rel="noopener" target="_blank" href="http://qiita.com/nao58/items/aa50514d97f05eb8d128">Rakeタスクで普通の引数っぽい処理を書く &#8211; Qiita<span class="fa fa-external-link external-icon anchor-icon"></span></a></li>
</ul>
<p>上記のサイトでは「環境変数」と「タスク引数」の渡し方がありますが、手元の10.0.4だと、タスク引数は1つの場合のみ正常に動作しました。</p>
<blockquote><p>~$ rake &#8211;version<br />
rake, version 10.0.4</p></blockquote>
<p>依存関係をさかのぼる際、引数を渡せないので、ちょっと面倒ですが、環境変数として渡す方法を採用したほうが良い場合があるかもしれません。<br />
（環境変数は依存先でも参照可能なため）</p>
<p>以上です。</p>
<ul></ul><p>The post <a href="https://freestyle.nvo.jp/archives/1913">いまさらRakeについての覚書</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Jekyll(Octopress)で画像パスを勝手に指定してくれるLiquidタグの作成</title>
		<link>https://freestyle.nvo.jp/archives/1883?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=jekylloctopress%25e3%2581%25a7%25e7%2594%25bb%25e5%2583%258f%25e3%2583%2591%25e3%2582%25b9%25e3%2582%2592%25e5%258b%259d%25e6%2589%258b%25e3%2581%25ab%25e6%258c%2587%25e5%25ae%259a%25e3%2581%2597%25e3%2581%25a6%25e3%2581%258f%25e3%2582%258c%25e3%2582%258bliquid%25e3%2582%25bf%25e3%2582%25b0%25e3%2581%25ae</link>
		
		<dc:creator><![CDATA[山平]]></dc:creator>
		<pubDate>Mon, 18 Jan 2016 00:47:22 +0000</pubDate>
				<category><![CDATA[技術情報]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[オープンソース]]></category>
		<category><![CDATA[ツール]]></category>
		<category><![CDATA[プラグイン]]></category>
		<guid isPermaLink="false">http://freestyle.nvo.jp/?p=1883</guid>

					<description><![CDATA[<p>前回、Jekyll(Octopress)の記事生成時に、記事用のディレクトリと、画像用のディレクトリを作成しました。 Jekyll(Octopress)の投稿を勝手にディレクトリ管理させる &#124; FreeStyleVisi [&#8230;]</p>
<p>The post <a href="https://freestyle.nvo.jp/archives/1883">Jekyll(Octopress)で画像パスを勝手に指定してくれるLiquidタグの作成</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>前回、Jekyll(Octopress)の記事生成時に、記事用のディレクトリと、画像用のディレクトリを作成しました。</p>
<ul>
<li><a rel="noopener" target="_blank" href="http://freestyle.nvo.jp/archives/1870">Jekyll(Octopress)の投稿を勝手にディレクトリ管理させる | FreeStyleVision<span class="fa fa-external-link external-icon anchor-icon"></span></a></li>
</ul>
<p>折角、画像用のディレクトリを作成しても、パスの指定までは面倒見てくれないので、あまり便利になった実感が沸きません。</p>
<p>そこで今回は、画像のパスを勝手に指定してくれるように手を加えていきます。</p>
<p><span id="more-1883"></span></p>
<p>Jekyllでは、テンプレートエンジンにLiquidを利用しているので、Liquidタグを追加する形で拡張すれば良いとのこと。</p>
<ul>
<li><a rel="noopener" target="_blank" href="http://www.xmisao.com/2013/09/16/how-to-make-a-jekyll-tag.html">jekyllプラグインの作り方 タグ編 &#8212; ぺけみさお<span class="fa fa-external-link external-icon anchor-icon"></span></a></li>
</ul>
<p>簡単そうなのでサクサク作って…と思いきや、画像のURLをうまく指定するのが難しいことに気がつきました。<br />
そこで、前回の<span>new_post2コマンドを少し直して、実装を楽にします。</span></p>
<p>以下、Rakefileの抜粋です。</p>
<p>[ruby]<br />
images_dir      = &#8220;images&#8221;    # directory for blog images</p>
<p>require &#8216;yaml&#8217;<br />
desc &#8220;Begin a new post in #{&#8220;config.yml[post2_dir_format]&#8221;}/#{posts_dir}&#8221;<br />
task :new_post2, :title do |t, args|<br />
if args.title<br />
title = args.title<br />
else<br />
title = get_stdin(&#8220;Enter a title for your post: &#8220;)<br />
end<br />
raise &#8220;### You haven&#8217;t set anything up yet. First run `rake install` to set up an Octopress theme.&#8221; unless File.directory?(source_dir)<br />
jekyll_config = YAML.load_file(&#8216;_config.yml&#8217;)<br />
time = Time.now<br />
filename = &#8220;#{time.strftime(&#8216;%Y-%m-%d&#8217;)}-#{title.to_url}&#8221;<br />
_dir = time.strftime(jekyll_config[&#8216;post2_dir_format&#8217;])<br />
posts_dir_ex = File.join(posts_dir, _dir, filename).gsub(/\/$/, &#8221;)<br />
image_dir_ex = File.join(images_dir, _dir, filename).gsub(/\/$/, &#8221;)<br />
mkdir_p &#8220;#{source_dir}/#{posts_dir_ex}&#8221;<br />
mkdir_p &#8220;#{source_dir}/#{image_dir_ex}&#8221;<br />
filename = &#8220;#{source_dir}/#{posts_dir_ex}/#{time.strftime(&#8216;%Y-%m-%d&#8217;)}-#{title.to_url}.#{new_post_ext}&#8221;<br />
if File.exist?(filename)<br />
abort(&#8220;rake aborted!&#8221;) if ask(&#8220;#{filename} already exists. Do you want to overwrite?&#8221;, [&#8216;y&#8217;, &#8216;n&#8217;]) == &#8216;n&#8217;<br />
end<br />
puts &#8220;Creating new post: #{filename}&#8221;<br />
open(filename, &#8216;w&#8217;) do |post|<br />
post.puts &#8220;&#8212;&#8221;<br />
post.puts &#8220;layout: post&#8221;<br />
post.puts &#8220;title: \&#8221;#{title.gsub(/&amp;/,&#8217;&amp;&#8217;)}\&#8221;&#8221;<br />
post.puts &#8220;date: #{time.strftime(&#8216;%Y-%m-%d %H:%M:%S %z&#8217;)}&#8221;<br />
post.puts &#8220;comments: true&#8221;<br />
post.puts &#8220;categories: &#8221;<br />
post.puts &#8220;image_dir: /#{image_dir_ex}&#8221;<br />
post.puts &#8220;&#8212;&#8221;<br />
end<br />
`gedit #{filename}`<br />
`nautilus #{source_dir}/#{image_dir_ex}`<br />
end<br />
[/ruby]</p>
<p>要は、画像ディレクトリを作成したタイミングでYAML Front Matterにディレクトリパスを追加することで、pageオブジェクトでアクセスできるようにします。<br />
これで実装が簡単になったはずなので、さっそく作ってみます。</p>
<p>[ruby]<br />
module Jekyll<br />
class HomeImageTag &lt; Liquid::Tag<br />
def initialize(tag_name, markup, tokens)<br />
_p = markup.strip.split(/\s/)<br />
@src = _p.shift<br />
@alt = _p.join(&#8221; &#8220;).strip<br />
super<br />
end</p>
<p>def render(context)<br />
page = context[&#8216;page&#8217;]<br />
path = File.join(page[&#8216;image_dir&#8217;], @src)<br />
return &lt;&lt;-&#8220;EOD&#8221;<br />
<img decoding="async" src="#{path}" alt="#{@alt}" /><br />
EOD<br />
end<br />
end<br />
end</p>
<p>Liquid::Template.register_tag(&#8216;home_img&#8217;, Jekyll::HomeImageTag)</p>
<p>[/ruby]</p>
<p>このコマンドで「rake new_post2[hoge]」とすると、YAML Front Matter「img_dir」が追加されたエントリの雛形が作成されます。<br />
ここに作成した「hime_img」Liquidタグを書いていきます。<br />
使うときは「home_img」タグに画像のファイル名とaltテキストを指定するだけです。<br />
比較用にマークダウンでも画像を指定しています。</p>
<blockquote><p>&#8212;<br />
layout: post<br />
title: &#8220;hoge&#8221;<br />
date: 2015-12-13 22:25:20 +0900<br />
comments: true<br />
categories:<br />
image_dir: /images/2015/1213/2015-12-13-hoge<br />
&#8212;<br />
markdown:<br />
![hoge hoge ho](/images/2015/1213/2015-12-13-hoge/test.png)<br />
plugin:<br />
{% home_img test.png hoge hoge ho %}</p></blockquote>
<p>マークダウンでパスを指定した場合と同じ画像が表示されています。</p>
<p><img fetchpriority="high" decoding="async" class="aligncenter size-full wp-image-1890" title="result" src="https://freestyle.nvo.jp/__wp__/wp-content/uploads/2015/12/result.png" alt="result" width="576" height="519" /></p>
<div>出力されるHTMLも大丈夫そうです。</div>
<div></div>
<div>
<div><div class="entry-content"></div>
<div><p></div>
<div>markdown:</div>
<div><img decoding="async" src="/images/2015/1213/2015-12-13-hoge/test.png" alt="hoge hoge ho"></div>
<div></p></div>
<div><p></div>
<div>plugin:</div>
<div><img decoding="async" src="/images/2015/1213/2015-12-13-hoge/test.png" alt="hoge hoge ho"></div>
<div></p></div>
<div></div></div>
</div>
<div></div>
<div></div>
<div>ここまでできると欲が出てマークダウンを拡張したくなります。</div>
<div>まだいい感じに実装できるイメージが掴めていないので、もう少し調査が必要です。</div>
<div></div>
<div>今回は以上です。</div><p>The post <a href="https://freestyle.nvo.jp/archives/1883">Jekyll(Octopress)で画像パスを勝手に指定してくれるLiquidタグの作成</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Jekyll(Octopress)の投稿を勝手にディレクトリ管理させる</title>
		<link>https://freestyle.nvo.jp/archives/1870?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=jekylloctopress%25e3%2581%25ae%25e6%258a%2595%25e7%25a8%25bf%25e3%2582%2592%25e5%258b%259d%25e6%2589%258b%25e3%2581%25ab%25e3%2583%2587%25e3%2582%25a3%25e3%2583%25ac%25e3%2582%25af%25e3%2583%2588%25e3%2583%25aa%25e7%25ae%25a1%25e7%2590%2586%25e3%2581%2595%25e3%2581%259b%25e3%2582%258b</link>
		
		<dc:creator><![CDATA[山平]]></dc:creator>
		<pubDate>Tue, 08 Dec 2015 06:16:42 +0000</pubDate>
				<category><![CDATA[技術情報]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[オープンソース]]></category>
		<guid isPermaLink="false">http://freestyle.nvo.jp/?p=1870</guid>

					<description><![CDATA[<p>それなりにイケてる静的サイトが簡単に作れるJekyllはとても便利です。 Jekyll • シンプルで、ブログのような、静的サイト さらにちょっと面倒な下準備まで済ませてくれているOctpressが私のお気に入りです O [&#8230;]</p>
<p>The post <a href="https://freestyle.nvo.jp/archives/1870">Jekyll(Octopress)の投稿を勝手にディレクトリ管理させる</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>それなりにイケてる静的サイトが簡単に作れるJekyllはとても便利です。</p>
<ul>
<li><a rel="noopener" target="_blank" href="http://jekyllrb-ja.github.io/">Jekyll • シンプルで、ブログのような、静的サイト<span class="fa fa-external-link external-icon anchor-icon"></span></a></li>
</ul>
<p>さらにちょっと面倒な下準備まで済ませてくれているOctpressが私のお気に入りです</p>
<ul>
<li><a rel="noopener" target="_blank" href="http://octopress.org/">Octopress<span class="fa fa-external-link external-icon anchor-icon"></span></a></li>
</ul>
<p>Jekyllにはちょっとだけ気に入らないところがあって、記事を１つのディレクトリ内に延々と書き溜めていかなければならない点でした。<br />
過去にテキストベースでCMSを自作した際に、同じ問題でとても苦労したことがあったからです。</p>
<p>ところがある日以下のような記事を見かけました。</p>
<ul>
<li><a rel="noopener" target="_blank" href="http://blog.glidenote.com/blog/2012/06/10/octopress-post-directory/">Octopressは_postsの下にディレクトリ切っても記事が生成される &#8211; Glide Note &#8211; グライドノート<span class="fa fa-external-link external-icon anchor-icon"></span></a></li>
</ul>
<p>なんと。。<br />
ちゃんとソースを読まないとダメですね。。</p>
<p><span id="more-1870"></span></p>
<p>ということで、新たに記事を作成する際にあらかじめ階層を切るようにRakefileを修正します。<br />
安直ですが、長いのは嫌なので「:new_post2」と言う名前のタスク名にしました。</p>
<p>[ruby]<br />
require &#8216;yaml&#8217;<br />
# usage rake new_post[my-new-post] or rake new_post[&#8216;my new post&#8217;] or rake new_post (defaults to &#8220;new-post&#8221;)<br />
desc &#8220;Begin a new post in #{source_dir}/#{posts_dir}&#8221;<br />
task :new_post2, :title do |t, args|<br />
if args.title<br />
title = args.title<br />
else<br />
title = get_stdin(&#8220;Enter a title for your post: &#8220;)<br />
end<br />
raise &#8220;### You haven&#8217;t set anything up yet. First run `rake install` to set up an Octopress theme.&#8221; unless File.directory?(source_dir)</p>
<p>jekyll_config = YAML.load_file(&#8216;_config.yml&#8217;)<br />
compass_config = IO.read(&#8216;config.rb&#8217;)<br />
images_dir_setting = compass_config.split(/\r?\n/).select {|line| line =~ /^\s*images_dir\s*=.+$/  }.pop<br />
images_dir = images_dir_setting.split(&#8220;=&#8221;).pop.gsub(/(\s|&#8221;)/, &#8220;&#8221;)</p>
<p>time = Time.now<br />
_posts_dir = time.strftime(jekyll_config[&#8216;post2_dir_format&#8217;])<br />
posts_dir_ex = File.join(posts_dir, _posts_dir).gsub(/\/$/, &#8221;)<br />
filename = &#8220;#{time.strftime(&#8216;%Y-%m-%d&#8217;)}-#{title.to_url}&#8221;<br />
filepath = File.join(source_dir, posts_dir_ex, &#8220;#{filename}.#{new_post_ext}&#8221;)<br />
imagepath = File.join(images_dir, _posts_dir, &#8220;#{filename}.images&#8221;)</p>
<p>mkdir_p &#8220;#{source_dir}/#{posts_dir_ex}&#8221;<br />
mkdir_p imagepath<br />
if File.exist?(filepath)<br />
abort(&#8220;rake aborted!&#8221;) if ask(&#8220;#{filepath} already exists. Do you want to overwrite?&#8221;, [&#8216;y&#8217;, &#8216;n&#8217;]) == &#8216;n&#8217;<br />
end<br />
puts &#8220;Creating new post: #{filepath}&#8221;<br />
open(filepath, &#8216;w&#8217;) do |post|<br />
post.puts &#8220;&#8212;&#8221;<br />
post.puts &#8220;layout: post&#8221;<br />
post.puts &#8220;title: \&#8221;#{title.gsub(/&amp;/,&#8217;&amp;amp;&#8217;)}\&#8221;&#8221;<br />
post.puts &#8220;date: #{Time.now.strftime(&#8216;%Y-%m-%d %H:%M:%S %z&#8217;)}&#8221;<br />
post.puts &#8220;comments: true&#8221;<br />
post.puts &#8220;categories: &#8221;<br />
post.puts &#8220;&#8212;&#8221;<br />
end</p>
<p>`gedit #{filepath}`<br />
`nautilus #{imagepath}`<br />
end<br />
[/ruby]</p>
<p>ついでなので、画像格納用のディレクトリも「images」配下に同様の階層を作成し、geditとnautilusで開くようにしてみました。</p>
<pre>$ rake new_post2[test]</pre>
<pre>mkdir -p source/_posts/2015/1105/2015-11-05-test</pre>
<pre>mkdir -p source/images/2015/1105/2015-11-05-test.images</pre>
<pre>Creating new post: source/_posts/2015/1105/2015-11-05-test/2015-11-05-test.markdown</pre>
<pre>$</pre>
<p>こんな内容でテストしてみます。</p>
<pre>---</pre>
<pre>layout: post</pre>
<pre>title: "test"</pre>
<pre>date: 2015-11-05 22:08:58 +0900</pre>
<pre>comments: true</pre>
<pre>categories:</pre>
<pre>---</pre>
<pre>![aaa](/images/2015/1105/2015-11-05-test.images/test.png)</pre>
<p><a rel="attachment wp-att-1875 noopener" target="_blank" href="http://freestyle.nvo.jp/archives/1870/screenshot-from-2015-11-05-2214041"><img decoding="async" class="aligncenter size-full wp-image-1875" title="screenshot-from-2015-11-05-2214041" src="https://freestyle.nvo.jp/__wp__/wp-content/uploads/2015/11/screenshot-from-2015-11-05-2214041.png" alt="screenshot-from-2015-11-05-2214041" width="320" height="280" /></a></p>
<p>いい感じです。<br />
…が、画像のパスを指定するのが面倒くさいですね。。<br />
次回以降、対策を考えてみます。</p><p>The post <a href="https://freestyle.nvo.jp/archives/1870">Jekyll(Octopress)の投稿を勝手にディレクトリ管理させる</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Bashから別階層のRubyプログラムを呼んだらBundlerがGemfileを読めない</title>
		<link>https://freestyle.nvo.jp/archives/1690?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=bash%25e3%2581%258b%25e3%2582%2589%25e5%2588%25a5%25e9%259a%258e%25e5%25b1%25a4%25e3%2581%25aeruby%25e3%2583%2597%25e3%2583%25ad%25e3%2582%25b0%25e3%2583%25a9%25e3%2583%25a0%25e3%2582%2592%25e5%2591%25bc%25e3%2582%2593%25e3%2581%25a0%25e3%2582%2589bundler%25e3%2581%258cgemfile%25e3%2582%2592%25e8%25aa%25ad</link>
		
		<dc:creator><![CDATA[山平]]></dc:creator>
		<pubDate>Thu, 12 Feb 2015 01:36:37 +0000</pubDate>
				<category><![CDATA[技術情報]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[オープンソース]]></category>
		<category><![CDATA[トラブルシュート]]></category>
		<guid isPermaLink="false">http://freestyle.nvo.jp/?p=1690</guid>

					<description><![CDATA[<p>最近…でもないですが、Ruby界隈ではBundlerを使って環境を保証するのがトレンドのようです。 Bundler: The best way to manage a Ruby application&#8217;s g [&#8230;]</p>
<p>The post <a href="https://freestyle.nvo.jp/archives/1690">Bashから別階層のRubyプログラムを呼んだらBundlerがGemfileを読めない</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>最近…でもないですが、Ruby界隈ではBundlerを使って環境を保証するのがトレンドのようです。</p>
<ul>
<li><a rel="noopener" target="_blank" href="http://bundler.io/">Bundler: The best way to manage a Ruby application&#8217;s gems<span class="fa fa-external-link external-icon anchor-icon"></span></a></li>
</ul>
<p><span id="more-1690"></span></p>
<p>私の場合、その場限りの書き捨てツールを書くことが多いので馴染みがあまりありません。<br />
しかし、世の流れには従うべきかと思っていた時期に少しだけ使ったことがあります。</p>
<p>これがいけなかった。</p>
<p>先日とあるバッチプログラムを作成した際、bundlerを利用したrubyプログラムを呼び出して利用しようとしたのですが、うまく動きません。</p>
<pre>$ ./fuga.sh
Could not locate Gemfile
$</pre>
<ul>
<li>fuga.shは、別の階層にあるhoge.rbを呼び出しています。</li>
<li>hoge.rbは単体では正しく動くのが確認できています。</li>
<li>rubyプログラム内のrequireで失敗しているようです</li>
</ul>
<p>BundlerがGemfileを読めていないと踏んで情報を探してみるのですが、Ruby=&gt;Rubyでの情報が見つかるばかり。。。<br />
仕方がないので見つけた情報を元にアタリをつけながら試行錯誤した結果が以下になります。</p>
<pre>ruby_program=../../hoge/hoge.rb
gem_bk=$BUNDLE_GEMFILE
export BUNDLE_GEMFILE="../../hoge/Gemfile"

bundle exec ruby $ruby_program

export BUNDLE_GEMFILE=$gem_bk</pre>
<p>Bundlerは環境変数BUNDLE_GEMFILEを元にGemfileを探すので、それを書き換えて目的のRubyプログラムを実行、終わったらバックアップから書き戻す、ということを行なっています。</p>
<p>以上です。</p><p>The post <a href="https://freestyle.nvo.jp/archives/1690">Bashから別階層のRubyプログラムを呼んだらBundlerがGemfileを読めない</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Nokogiriでうまく解析できなかった場合の対処</title>
		<link>https://freestyle.nvo.jp/archives/1683?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=nokogiri%25e3%2581%25a7%25e3%2581%2586%25e3%2581%25be%25e3%2581%258f%25e8%25a7%25a3%25e6%259e%2590%25e3%2581%25a7%25e3%2581%258d%25e3%2581%25aa%25e3%2581%258b%25e3%2581%25a3%25e3%2581%259f%25e5%25a0%25b4%25e5%2590%2588%25e3%2581%25ae%25e5%25af%25be%25e5%2587%25a6</link>
		
		<dc:creator><![CDATA[山平]]></dc:creator>
		<pubDate>Tue, 27 Jan 2015 12:26:52 +0000</pubDate>
				<category><![CDATA[技術情報]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[トラブルシュート]]></category>
		<guid isPermaLink="false">http://freestyle.nvo.jp/?p=1683</guid>

					<description><![CDATA[<p>Rubyでスクレイピングするなら、Nokogiriが定番です。 概ねDOMに忠実な実装でありながら、rubyらしく書きたいポイントは押さえている心憎いライブラリです。 Nokogiri 鋸 ところが先日、Nokogiri [&#8230;]</p>
<p>The post <a href="https://freestyle.nvo.jp/archives/1683">Nokogiriでうまく解析できなかった場合の対処</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Rubyでスクレイピングするなら、Nokogiriが定番です。<br />
概ねDOMに忠実な実装でありながら、rubyらしく書きたいポイントは押さえている心憎いライブラリです。</p>
<ul>
<li><a rel="noopener" target="_blank" href="http://www.nokogiri.org/">Nokogiri 鋸<span class="fa fa-external-link external-icon anchor-icon"></span></a></li>
</ul>
<p>ところが先日、Nokogiriを使ってWebページをスクレイピングしていた時に、上手くノードが取得できない場面に遭遇しましたので、備忘録としてここに残します。</p>
<p><span id="more-1683"></span></p>
<p>まずは通常通りにタグを取得します。<br />
この時のxpathはソースコードを確認して、絶対に存在するものが指定されています。</p>
<p>[ruby]<br />
&gt;&gt; require &#8216;nokogiri&#8217;<br />
=&gt; true<br />
&gt;&gt; require &#8216;open-uri&#8217;<br />
=&gt; true<br />
&gt;&gt; url=&#8221;http://hoge.fuga.com&#8221;<br />
=&gt; &#8220;http://hoge.fuga.com&#8221;<br />
&gt;&gt; doc=Nokogiri::HTML(open(url){|f|f.read})<br />
=&gt; （割愛)<br />
&gt;&gt; zzz=doc.xpath(&#8220;//p[@class=&#8217;zzz&#8217;]&#8221;)<br />
=&gt; []<br />
[/ruby]</p>
<p>タグが取得できていません。<br />
一体なぜなのでしょうか。</p>
<p>色々と試してみた結果、どうやら原因は「難読化されたJavaScriptコード」のようです。<br />
本来なら機械的な意味で無駄が少なくなっているはずなのですが、Nokogiriと相性が悪いのでしょうか。</p>
<p>仕方がないので、&lt;script&gt;〜&lt;/script&gt;を正規表現で取り除きます。<br />
元々NokogiriはJavaScriptを実行できないので、あまり問題ないと判断しました。</p>
<p>[ruby]<br />
&gt;&gt; require &#8216;nokogiri&#8217;<br />
=&gt; true<br />
&gt;&gt; require &#8216;open-uri&#8217;<br />
=&gt; true<br />
&gt;&gt; url=&#8221;http://hoge.fuga.com&#8221;<br />
=&gt; &#8220;http://hoge.fuga.com&#8221;<br />
&gt;&gt; html=(open(url){|f|f.read}).gsub!(/&lt;script[^&gt;]*&gt;.*?&lt;\/script&gt;/g, &#8220;&#8221;)<br />
=&gt; （割愛)<br />
&gt;&gt; doc=Nokogiri::HTML(html)<br />
=&gt; （割愛)<br />
&gt;&gt; zzz=doc.xpath(&#8220;//p[@class=&#8217;zzz&#8217;]&#8221;)<br />
=&gt; [&lt;Nokogiri::Node&gt;]<br />
[/ruby]</p>
<p>なお、最近はヘッダ要素内ではなく、HTML中や末尾にscriptタグを記述することが増えてきました。<br />
このため、正規表現は最短マッチさせるように記述しないと、本来必要な要素まで削除してしまうので、注意が必要です。</p>
<p>以上です。</p><p>The post <a href="https://freestyle.nvo.jp/archives/1683">Nokogiriでうまく解析できなかった場合の対処</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>RubyがSeleniumと相性がいい話</title>
		<link>https://freestyle.nvo.jp/archives/1562?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ruby%25e3%2581%258cselenium%25e3%2581%25a8%25e7%259b%25b8%25e6%2580%25a7%25e3%2581%258c%25e3%2581%2584%25e3%2581%2584%25e8%25a9%25b1</link>
		
		<dc:creator><![CDATA[山平]]></dc:creator>
		<pubDate>Wed, 19 Mar 2014 13:33:58 +0000</pubDate>
				<category><![CDATA[技術情報]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[ツール]]></category>
		<guid isPermaLink="false">http://freestyle.nvo.jp/?p=1562</guid>

					<description><![CDATA[<p>自動テストで有名なSeleniumですが、核になる技術はブラウザを自動運転するWebDriverです。 これを使えば、ブラウザが必要な操作も自動化できてしまいます。 RubyでSeleniumを使ってスクレイピング &# [&#8230;]</p>
<p>The post <a href="https://freestyle.nvo.jp/archives/1562">RubyがSeleniumと相性がいい話</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>自動テストで有名なSeleniumですが、核になる技術はブラウザを自動運転するWebDriverです。<br />
これを使えば、ブラウザが必要な操作も自動化できてしまいます。</p>
<ul>
<li><a rel="noopener" target="_blank" href="http://qiita.com/tomerun/items/9cb81d7a98150ff22f53">RubyでSeleniumを使ってスクレイピング &#8211; Qiita [キータ]<span class="fa fa-external-link external-icon anchor-icon"></span></a></li>
</ul>
<p>RubyとSeleniumは非常に相性が良いと感じます。</p>
<p><span id="more-1562"></span></p>
<p>SeleniumというよりもWebページの構造上、クリック後の処理待ちなどが発生するため、プログラム的に美しく記述することが難しいことがよくあります。<br />
また、ブラウザ操作を行うプログラムは、ログイン・ログアウトといった共通処理が少なくありません。<br />
ブロック付きメソッドを簡単に実装できるRubyだと、そのへんをすっきりと記述することができます。</p>
<p>今回は、社内で使用しているグループウェアの処理を自動化してみました。<br />
公開できない部分だけ差し替えたソースコードを公開します。</p>
<ul>
<li><a href="https://freestyle.nvo.jp/__wp__/wp-content/uploads/2014/02/20140202_selenium_with_ruby_sample.zip">20140202_selenium_with_ruby_sample<span class="fa fa-link internal-icon anchor-icon"></span></a></li>
</ul>
<p>ここからはソースコードの説明になります。</p>
<h3><span id="toc1">設定ファイル</span></h3>
<p>ログイン情報などはYAMLで外出しにしています。<br />
YAMLは扱いも楽なので、設定ファイルのフォーマットに悩む必要がないのも何気に嬉しいポイントですね。</p>
<h3><span id="toc2">login_actionメソッド</span></h3>
<p>login_actionメソッド内では、以下の処理を行います。</p>
<ul>
<li>ブラウザの起動</li>
<li>ログイン</li>
<li>ブロックの実行 ※ここがポイント！</li>
<li>ログアウト（はしていないケド。。。）</li>
<li>ブラウザの終了</li>
</ul>
<p>ここにはブラウザ操作の基本のみを記述しており、具体的な操作はブロックで受け取る、という記述が簡単なのが非常に楽です。</p>
<h3><span id="toc3">hyogo_iineメソッド</span></h3>
<p>hyogo_iineという具体的な処理を行うメソッドを定義します。<br />
ここでは、掲示板のすべての書き込みの「いいね！」をクリックしています。</p>
<p>最初に書きましたが、クリック後の処理待ちの記述は面倒です。<br />
今回の「いいね！」はクリックするとAjaxが走るので、特に面倒くさい処理になるのですが、ここでRubyの表現力が活きてきます。</p>
<blockquote><p>break if browser.find_elements(:xpath, xpath).all?{|span| !span.displayed? }</p></blockquote>
<p>まず、読み込み待ちのときに表示される画像をすべて取得します。<br />
Array#all?メソッドで、すべて非表示かどうかを調べます。<br />
表示中の読み込み待ち画像が残っていたら、1秒待って処理を繰り返します。</p>
<h3><span id="toc4">文末</span></h3>
<p>最後に、クラスファイルが他のRubyプログラムから呼ばれていない場合の処理を記述しています。<br />
こうすることで、組み込んで使うことも、コマンドラインプログラムとして利用することも可能になります。</p><p>The post <a href="https://freestyle.nvo.jp/archives/1562">RubyがSeleniumと相性がいい話</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>herokuを試した記録</title>
		<link>https://freestyle.nvo.jp/archives/1460?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=heroku%25e3%2582%2592%25e8%25a9%25a6%25e3%2581%2597%25e3%2581%259f%25e8%25a8%2598%25e9%258c%25b2</link>
		
		<dc:creator><![CDATA[山平]]></dc:creator>
		<pubDate>Mon, 26 Aug 2013 00:35:31 +0000</pubDate>
				<category><![CDATA[技術情報]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Webサービス]]></category>
		<category><![CDATA[クラウド]]></category>
		<category><![CDATA[開発環境]]></category>
		<guid isPermaLink="false">http://freestyle.nvo.jp/?p=1460</guid>

					<description><![CDATA[<p>Webサービスを作りたくなったとき、プロトタイプはsinatraでサクッと試したいのですが、いくつか問題があります。 sinatraはRackで動く Apacheでsinatraを動かそうと思うとCGIとして動作してしま [&#8230;]</p>
<p>The post <a href="https://freestyle.nvo.jp/archives/1460">herokuを試した記録</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Webサービスを作りたくなったとき、プロトタイプは<a rel="noopener" target="_blank" href="http://www.sinatrarb.com/">sinatra<span class="fa fa-external-link external-icon anchor-icon"></span></a>でサクッと試したいのですが、いくつか問題があります。</p>
<ul>
<li><a rel="noopener" target="_blank" href="http://www.sinatrarb.com/">sinatra<span class="fa fa-external-link external-icon anchor-icon"></span></a>は<a rel="noopener" target="_blank" href="http://rack.github.io/">Rack<span class="fa fa-external-link external-icon anchor-icon"></span></a>で動く</li>
<li>Apacheで<a rel="noopener" target="_blank" href="http://www.sinatrarb.com/">sinatra<span class="fa fa-external-link external-icon anchor-icon"></span></a>を動かそうと思うとCGIとして動作してしまう<br />
→<a rel="noopener" target="_blank" href="https://www.phusionpassenger.com/">Passenger（mod_rack）<span class="fa fa-external-link external-icon anchor-icon"></span></a>というものがあるらしい（未調査）</li>
<li>CGIの<a rel="noopener" target="_blank" href="http://www.sinatrarb.com/">sinatra<span class="fa fa-external-link external-icon anchor-icon"></span></a>は遅い</li>
</ul>
<p>sinatraがサクサク動いて規模の小さいうちは無料で使える環境を探したところ、<a rel="noopener" target="_blank" href="https://www.heroku.com/">heroku<span class="fa fa-external-link external-icon anchor-icon"></span></a>でもいけるとのこと。<br />
<a rel="noopener" target="_blank" href="https://www.heroku.com/">heroku<span class="fa fa-external-link external-icon anchor-icon"></span></a>はRubyOnRailsを使うためのサービスだと思っていたら最近は色々使えるようなので試してみることにします。</p>
<p><span id="more-1460"></span></p>
<h3><span id="toc1">登録</span></h3>
<p><a rel="noopener" target="_blank" href="https://www.heroku.com/">heroku<span class="fa fa-external-link external-icon anchor-icon"></span></a>にアクセスして「sign up for free」からメールアドレスを入力します。<br />
入力したメールアドレスにアクティベーションURLが飛んでくるのでクリックした先でパスワードを登録して完了。</p>
<h3><span id="toc2">herokuコマンドのインストール</span></h3>
<p>「まずはHeroku Toolbeltを入れなさい」的なメッセージがど真ん中に表示されるので、OSを選んでインストール。<br />
Ubuntuなのでコンソールから</p>
<blockquote><p>wget -qO- https://toolbelt.heroku.com/install-ubuntu.sh | sh</p></blockquote>
<p>と入力すると、色々入って完了。</p>
<h3><span id="toc3">クイックスタート</span></h3>
<p>ターミナルを開いてダッシュボードの真ん中に表示されているコマンドを順に入力します。</p>
<blockquote><p>You don&#8217;t have any apps; deploy a sample application.</p>
<p>$ git clone git://github.com/heroku/ruby-sample.git<br />
$ cd ruby-sample<br />
$ heroku create<br />
$ git push heroku master<br />
$ heroku open</p></blockquote>
<p>最後の一行「heroku open」を打ったらFirefoxが立ち上がって「Hello, world」と表示されました。<br />
なんともうアプリケーションが公開されてしまいました。</p>
<h3><span id="toc4">何が起こったのか？</span></h3>
<p>クイックスタートがクイックすぎて正直よく分からなかったので、順を追って理解を試みます。</p>
<blockquote><p>$ git clone git://github.com/heroku/ruby-sample.git</p></blockquote>
<p>サンプルアプリをリポジトリから取得</p>
<blockquote><p>$ cd ruby-sample</p></blockquote>
<p>サンプルアプリのディレクトリに移動</p>
<blockquote><p>$ heroku create</p></blockquote>
<p>herokuコマンドで自分のheroku上にアプリ領域を作った？<br />
※追って調査します。</p>
<blockquote><p>$ git push heroku master</p></blockquote>
<p>herokuはアプリがリポジトリで管理されているとのこと。</p>
<ul>
<li> <a href=" http://www.ownway.info/Ruby/index.php?heroku%2Fhow%2Fmanagement%2Fapplication#clone">インストール済みアプリケーションのソースコード取得 | Heroku アプリケーションの管理 &#8211; 君の瞳はまるでルビー &#8211; Ruby 関連まとめサイト<span class="fa fa-link internal-icon anchor-icon"></span></a><br />
<blockquote><p>Heroku にインストールしたアプリケーションは Heroku 上の Git で管理されており git clone コマンドによって取得できます。</p></blockquote>
</li>
</ul>
<blockquote><p>$ heroku open</p></blockquote>
<p>herokuコマンドでアプリを開く？<br />
※追って調査します。</p>
<h3><span id="toc5">ローカルファイル</span></h3>
<p>サンプルアプリケーションのローカルコピーは以下の4ファイルです。</p>
<ul>
<li>Gemfile</li>
<li>Gemfile.lock</li>
<li>Procfile</li>
<li>web.rb</li>
</ul>
<p>中身を見れば何となくやっていることは読み取れますし、聞いたことのあるキーワードもちらほらあります。<br />
でも触ったことのないモノばかりで時代に取り残されている感じがします。</p>
<p>聞いたことあるけどよく分かっていないキーワード（heroku以外で）</p>
<ul>
<li>git</li>
<li>Gemfile</li>
<li>bundle</li>
</ul>
<p>ネットで調べたら以下の情報がわかりやすかったので、今後使いながら覚えていこうと思います。</p>
<ul>
<li><a href=" http://sixeight.hatenablog.com/entry/20080514/1210755576">Git入門(さいしょのいっぽ編) &#8211; ちなみに<span class="fa fa-link internal-icon anchor-icon"></span></a></li>
<li><a rel="noopener" target="_blank" href="http://www.rubylife.jp/rails/ini/index2.html">Bundlerを使ったGemパッケージの管理 &#8211; Ruby on Rails入門<span class="fa fa-external-link external-icon anchor-icon"></span></a></li>
</ul>
<p>とりあえずあっという間に、そして何となくできてしまいましたが、（主に不勉強についての）課題も見つかりました。<br />
herokuコマンドについては追って調査します。</p>
<h3><span id="toc6">わかりやすい情報</span></h3>
<p>以下の記事がサービスを作りながら解説してくれていてとてもわかりやすかったです。</p>
<ul>
<li><a href=" http://www.machu.jp/diary/20111002.html#p01">Heroku上でSinatraアプリを動かすまでのまとめ &#8211; まちゅダイアリー(2011-10-02)<span class="fa fa-link internal-icon anchor-icon"></span></a></li>
</ul><p>The post <a href="https://freestyle.nvo.jp/archives/1460">herokuを試した記録</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Rubydoctestの挙動メモ</title>
		<link>https://freestyle.nvo.jp/archives/938?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=rubydoctest%25e3%2581%25ae%25e6%258c%2599%25e5%258b%2595%25e3%2583%25a1%25e3%2583%25a2</link>
		
		<dc:creator><![CDATA[山平]]></dc:creator>
		<pubDate>Fri, 06 Jan 2012 09:08:44 +0000</pubDate>
				<category><![CDATA[技術情報]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[ツール]]></category>
		<guid isPermaLink="false">http://freestyle.nvo.jp/?p=938</guid>

					<description><![CDATA[<p>前回、Rubydoctestのドキュメントを邦訳しました（rubydoctest &#8211; Example Usage の邦訳）。 本家のドキュメントも少ないのですが、他に情報らしい情報もほとんど見当たりません。  [&#8230;]</p>
<p>The post <a href="https://freestyle.nvo.jp/archives/938">Rubydoctestの挙動メモ</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>前回、Rubydoctestのドキュメントを邦訳しました<a href="../archives/931">（rubydoctest &#8211; Example Usage の邦訳）<span class="fa fa-link internal-icon anchor-icon"></span></a>。<br />
<a rel="noopener" target="_blank" href="https://github.com/tablatom/rubydoctest/wiki/">本家のドキュメント<span class="fa fa-external-link external-icon anchor-icon"></span></a>も少ないのですが、他に情報らしい情報もほとんど見当たりません。<br />
唯一見つけた情報も使い方というよりは紹介ですし、かなり古い記事です。</p>
<ul>
<li><a rel="noopener" target="_blank" href="http://www.infoq.com/jp/news/2008/07/ruby-doctest">DocTest 1.0 For Ruby リリース<span class="fa fa-external-link external-icon anchor-icon"></span></a></li>
</ul>
<p>なので使ってみた結果をここに記録しておきます。</p>
<p><span id="more-938"></span></p>
<h3><span id="toc1">呼び出しに関すること</span></h3>
<h4><span id="toc2">微妙なパス指定</span></h4>
<p>ファイル名の指定に&#8221;*(任意の文字列)&#8221;,&#8221;?(任意の文字)&#8221;が使えるようですが、&#8221;**(任意の階層)&#8221;は使えないようです。<br />
なので、</p>
<ul>
<li>./aaa/astk.rb</li>
<li>./aaa/bbb/msptmy.rb</li>
<li>./xxx/inds.rb</li>
</ul>
<p>上のような構成で&#8221;rubydoctest **/*.rb&#8221;とタイプしてもmsptmy.rbはテストされません。</p>
<blockquote><p>rubydoctest **/*.rb<br />
=== Testing &#8216;xxx/hoge.rb&#8217;&#8230;<br />
OK  | Default Test<br />
1 comparisons, 1 doctests, 0 failures, 0 errors<br />
=== Testing &#8216;aaa/astk.rb&#8217;&#8230;<br />
OK  | Default Test<br />
1 comparisons, 1 doctests, 0 failures, 0 errors</p></blockquote>
<p>ここはトップレベルの指定だけで全部テストしてほしいところです。</p>
<h4><span id="toc3">シンプルなirbセッションを貼り付ける</span></h4>
<p>irbの結果を張り付けるだけでテストコードが作成できるのは便利なのですが、シンプルなirbセッションを張り付けないと怒られてしまいます。<br />
「シンプルなirbセッション」とは、「&#8211;simple-prompt」オプションを指定して起動したirbセッションのプロンプトのことを意味しています。</p>
<p>シンプルでない（デフォルト）の場合</p>
<blockquote><p>$ irb<br />
irb(main):001:0&gt; 1+1<br />
=&gt; 2<br />
irb(main):002:0&gt;</p></blockquote>
<p>シンプルなirbセッションの場合</p>
<blockquote><p>$ /usr/bin/irb &#8211;simple-prompt<br />
&gt;&gt; 1*1<br />
=&gt; 1<br />
&gt;&gt;</p></blockquote>
<p>なので「.bashrc」にエイリアスをつけておくのがいいと思います。</p>
<blockquote><p>alias irb=&#8217;irb &#8211;simple-prompt&#8217;</p></blockquote>
<h3><span id="toc4">テストに関すること</span></h3>
<p>まず、挙動確認に使ったソースと動作結果を示します。</p>
<p>ソース「doctest.rb」</p>
<p>[ruby]<br />
#!/usr/bin/ruby</p>
<p>#doctest: 事前にインスタンスが作れる<br />
# テスト中は変数が生きているので、以降のテストでも利用可能<br />
# クラスの場合などに便利<br />
#&gt;&gt; d = Doctesttest.new<br />
#&gt;&gt; d.class<br />
#=&gt; Doctesttest<br />
class Doctesttest</p>
<p>#doctest: 足し算<br />
#&gt;&gt; d.add(1,2)<br />
#=&gt; 3<br />
def add(a, b); a + b; end</p>
<p>#doctestディレクティブがないと前のテストに<br />
#含まれている用に見えるけど、無視はされてないっぽい<br />
#&gt;&gt; d.sub(1,2)<br />
#=&gt; -1<br />
def sub(a, b); a &#8211; b; end</p>
<p>#doctest: ここでdoメソッドを試す<br />
# !!!ディレクティブで止める<br />
#!!!<br />
def do(expression); eval expression; end</p>
<p>#doctest: !!!ディレクティブはexitで抜ける<br />
# 抜けた後はrubydoctestのセッションに戻る<br />
# 2回&#8221;exit&#8221;とタイプしないといけないのはなぜ？<br />
#&gt;&gt; d.do &#8220;1+1&#8221;<br />
#=&gt; 2<br />
end<br />
[/ruby]</p>
<p>テスト結果</p>
<blockquote><p>$ rubydoctest doctest.rb<br />
=== Testing &#8216;doctest.rb&#8217;&#8230;<br />
OK  | テスト中の変数は最後まで生き残る<br />
なのでクラスのインスタンスを最初に作れば<br />
以降のメソッドで使いまわせる<br />
OK  | 足し算<br />
OK  | ここでdoメソッドを試す<br />
!!!ディレクティブで止める<br />
&gt;&gt; d.do &#8220;1+2+3&#8221;<br />
=&gt; 6<br />
&gt;&gt; exit<br />
&gt;&gt; exit<br />
OK  | !!!ディレクティブはexitで抜ける<br />
抜けた後はrubydoctestのセッションに戻る<br />
2回&#8221;exit&#8221;とタイプしないといけないのはなぜ？<br />
4 comparisons, 6 doctests, 0 failures, 0 errors<br />
$</p></blockquote>
<h4><span id="toc5">事前に宣言したオブジェクトを使える</span></h4>
<p>ソースの先頭でDoctesttestクラスのインスタンスを作成しています。<br />
テスト中はこのインスタンスが生きているので使い回すことができます。<br />
クラスのメソッドを確認するのに毎回オブジェクトを作る必要はありません。</p>
<h4><span id="toc6">doctestディレクティブ</span></h4>
<p>doctestディレクティブが記述されていないテストは「OK | メッセージ」という形式で結果が出力されませんが、テストとしてはカウントされているようです。<br />
（最後の「4 comparisons, 6 doctests」に注目）</p>
<p>クラスのテストの場合には、1メソッドに1doctestディレクティブで記述するのが読みやすそうです。</p>
<h4><span id="toc7">!!!ディレクティブ</span></h4>
<p>テストの途中でirbセッションを触ることができます。<br />
大量の自動テストの途中で止まってしまうことを考えると不便ですが、デバッグ中に毎回入力する内容までを自動化すると便利です。<br />
ただし、エラーが発生した場合、通常のirbセッションと違って変なスタックトレースが出力されてしまって問題のある箇所が特定できません。。。</p>
<p>テストにセッションを返す際は「exit」と入力すればよいとドキュメントにあるのですが、なぜか2回入力しないと戻りませんでした。</p>
<h3><span id="toc8">結論</span></h3>
<p>便利そうで意外と不便なのですが、それでも使いたくなる魅力を感じるのは私だけでしょうか？<br />
何を重視するかによっても評価は変わってくると思いますが、</p>
<ul>
<li>ソースファイルの中に一緒に記述できるので、忘れたころにソースを触る必要が合った場合にテストコード紛失の恐れがない</li>
<li>コメントとして記述するので<a rel="noopener" target="_blank" href="http://ruby.gfd-dennou.org/tutorial/rdoc/">rdoc<span class="fa fa-external-link external-icon anchor-icon"></span></a>等のドキュメントにもテストコードが出力され、一粒で二度おいしい（これもソースファイルだけの管理で紛失の心配がない）</li>
</ul>
<p>この二点にたまらない魅力を感じるのは、私の「作っては放置し、久しぶりに触っては苦労する」という習慣のせいなのでしょうが。。。</p>
<p>以上です。</p><p>The post <a href="https://freestyle.nvo.jp/archives/938">Rubydoctestの挙動メモ</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>レーベンシュタイン距離で文字列の類似度を測る</title>
		<link>https://freestyle.nvo.jp/archives/925?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e3%2583%25ac%25e3%2583%25bc%25e3%2583%2599%25e3%2583%25b3%25e3%2582%25b7%25e3%2583%25a5%25e3%2582%25bf%25e3%2582%25a4%25e3%2583%25b3%25e8%25b7%259d%25e9%259b%25a2%25e3%2581%25a7%25e6%2596%2587%25e5%25ad%2597%25e5%2588%2597%25e3%2581%25ae%25e9%25a1%259e%25e4%25bc%25bc%25e5%25ba%25a6%25e3%2582%2592%25e6%25b8%25ac%25e3%2582%258b</link>
		
		<dc:creator><![CDATA[山平]]></dc:creator>
		<pubDate>Fri, 18 Nov 2011 05:06:33 +0000</pubDate>
				<category><![CDATA[技術情報]]></category>
		<category><![CDATA[Ruby]]></category>
		<guid isPermaLink="false">http://freestyle.nvo.jp/?p=925</guid>

					<description><![CDATA[<p>過去にネットで見かけてその存在だけは知っていたレーベンシュタイン距離について追ってみます。 編集距離 (Levenshtein Distance) &#8211; naoyaのはてなダイアリー すでにrubyで実装されて [&#8230;]</p>
<p>The post <a href="https://freestyle.nvo.jp/archives/925">レーベンシュタイン距離で文字列の類似度を測る</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>過去にネットで見かけてその存在だけは知っていたレーベンシュタイン距離について追ってみます。<br />
<a rel="noopener" target="_blank" href="http://d.hatena.ne.jp/naoya/20090329/1238307757">編集距離 (Levenshtein Distance) &#8211; naoyaのはてなダイアリー<span class="fa fa-external-link external-icon anchor-icon"></span></a></p>
<p>すでにrubyで実装されている方がいらっしゃったので、それを使うことにします。<br />
<a rel="noopener" target="_blank" href="http://d.hatena.ne.jp/kenkitii/20090204/ruby_levenshtein_distance">ruby でレーベンシュタイン距離（編集距離）の計算 &#8211; Moderation is a fatal thing. Nothing succeeds like excess.<span class="fa fa-external-link external-icon anchor-icon"></span></a></p>
<p>（私的な）使い勝手向上のために以下2点の修正を加えています。</p>
<ol>
<li>Stringクラスを再オープンしてメソッドを定義</li>
<li>メソッド名をldに変更</li>
</ol>
<p><span id="more-925"></span></p>
<p>では早速動作をチェックしてみます。</p>
<blockquote><p>&#8220;氷山の一角&#8221;.ld &#8220;天山の一撃&#8221;<br />
=&gt; 6<br />
&#8220;ヘリコプター&#8221;.ld &#8220;ヘコリプター&#8221;<br />
=&gt; 4<br />
&#8220;じゃがいも&#8221;.ld &#8220;がじゃいも&#8221;<br />
=&gt; 5</p></blockquote>
<p>良さそうな気もしますが、3つとも2文字違いの割に結果（の距離）が長い気がします。<br />
と思ったら、これは恐らくRuby1.9向けの実装ですね。</p>
<p><a rel="noopener" target="_blank" href="http://doc.ruby-lang.org/ja/1.8.7/method/String/i/=5b=5d.html">Ruby 1.8.7 リファレンスマニュアル &gt; ライブラリ一覧 &gt; 組み込みライブラリ &gt; Stringクラス &gt; [] <span class="fa fa-external-link external-icon anchor-icon"></span></a></p>
<blockquote><p><span style="color: #ff0000;"><strong>nth 番目のバイトを整数 (文字コード) で返します。</strong></span><br />
nth が負の場合は文字列の末尾から数えます。<br />
つまり、 self.size + nth 番目のバイトを返します。</p></blockquote>
<p><a rel="noopener" target="_blank" href="http://doc.okkez.net/static/192/method/String/i/=5b=5d.html">Ruby 1.9.2 リファレンスマニュアル &gt; ライブラリ一覧 &gt; 組み込みライブラリ &gt; Stringクラス &gt; [] <span class="fa fa-external-link external-icon anchor-icon"></span></a></p>
<blockquote><p><span style="color: #0000ff;"><strong>nth 番目の文字を返します。</strong></span><br />
nth が負の場合は文字列の末尾から数えます。<br />
つまり、 self.size + nth 番目の文字を返します。</p></blockquote>
<p>1.8系の文字列は内部的にはただのバイト列、1.9系からは内部的にも文字の列なので、私の環境（1.8.7）では全角文字のバイト数ぶんカウントされているものと思われます。<br />
なので、文字列ではなく正規表現で分割して文字配列で処理させるように変更します。<br />
※uオプションを利用していますので、UTF-8以外は正しく処理しません！<br />
<a rel="noopener" target="_blank" href="http://doc.okkez.net/static/191/doc/spec=2fliteral.html#regexp">Ruby 1.9.1 リファレンスマニュアル &gt; spec/literal # 正規表現リテラル<span class="fa fa-external-link external-icon anchor-icon"></span></a></p>
<p>では、改めて動作をチェックします。</p>
<blockquote><p>&#8220;氷山の一角&#8221;.ld &#8220;天山の一撃&#8221;<br />
=&gt; 2<br />
&#8220;ヘリコプター&#8221;.ld &#8220;ヘコリプター&#8221;<br />
=&gt; 2<br />
&#8220;じゃがいも&#8221;.ld &#8220;がじゃいも&#8221;<br />
=&gt; 2</p></blockquote>
<p>これで予想通りの結果になりました。</p>
<p>以下が今回手を入れたソースです。<br />
[ruby]<br />
class String<br />
def ld(comp)<br />
str1, str2 = self.split(//u), comp.split(//u) # 1.8系対応(*UTF8!)<br />
col, row = str1.size + 1, str2.size + 1<br />
d = row.times.inject([]){|a, i| a &lt;&lt; [0] * col }<br />
col.times {|i| d[0][i] = i }<br />
row.times {|i| d[i][0] = i }<br />
str1.size.times do |i1|<br />
str2.size.times do |i2|<br />
cost = str1[i1] == str2[i2] ? 0 : 1<br />
x, y = i1 + 1, i2 + 1<br />
d[y][x] = [d[y][x-1]+1, d[y-1][x]+1, d[y-1][x-1]+cost].min<br />
end<br />
end<br />
d[str2.size][str1.size]<br />
end<br />
end<br />
[/ruby]</p>
<p>当たり前ですが、このアルゴリズムは単語同士の比較には有用でも、単語と文章の比較には使えません。</p>
<blockquote><p>&#8220;七転八倒&#8221;.ld &#8220;七転び八起き&#8221;<br />
=&gt; 3<br />
&#8220;七転八倒&#8221;.ld &#8220;人生は七転び八起きの精神だ&#8221;<br />
=&gt; 10</p></blockquote>
<p>似ているかもしれない2つの単語を抽出するところまでをどうすればよいのか、課題は尽きません。</p>
<p>以上です。</p><p>The post <a href="https://freestyle.nvo.jp/archives/925">レーベンシュタイン距離で文字列の類似度を測る</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>N-gramで文字列の類似度を測る</title>
		<link>https://freestyle.nvo.jp/archives/919?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=n-gram%25e3%2581%25a7%25e6%2596%2587%25e5%25ad%2597%25e5%2588%2597%25e3%2581%25ae%25e9%25a1%259e%25e4%25bc%25bc%25e5%25ba%25a6%25e3%2582%2592%25e6%25b8%25ac%25e3%2582%258b</link>
		
		<dc:creator><![CDATA[山平]]></dc:creator>
		<pubDate>Fri, 04 Nov 2011 00:33:17 +0000</pubDate>
				<category><![CDATA[技術情報]]></category>
		<category><![CDATA[Ruby]]></category>
		<guid isPermaLink="false">http://freestyle.nvo.jp/?p=919</guid>

					<description><![CDATA[<p>とある2つの文字列がどれぐらい似ているのかを比較するにはどうすればいいのかを調べる必要があったので、ネットで検索してみました。 perlにはString::Trigramというモジュールがあるようです。 String:: [&#8230;]</p>
<p>The post <a href="https://freestyle.nvo.jp/archives/919">N-gramで文字列の類似度を測る</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>とある2つの文字列がどれぐらい似ているのかを比較するにはどうすればいいのかを調べる必要があったので、ネットで検索してみました。<br />
perlには<a rel="noopener" target="_blank" href="http://search.cpan.org/dist/String-Trigram/Trigram.pm">String::Trigram<span class="fa fa-external-link external-icon anchor-icon"></span></a>というモジュールがあるようです。</p>
<p><a rel="noopener" target="_blank" href="http://blog.livedoor.jp/techblog/archives/64737211.html">String::Trigram でテキストの類似度を測る<span class="fa fa-external-link external-icon anchor-icon"></span></a></p>
<p>rubyで同じようなものが見つからなかったので、取り急ぎ作って見ました。</p>
<p><span id="more-919"></span></p>
<p>[ruby]<br />
#!/usr/bin/ruby</p>
<p>#類似度の比較<br />
class String<br />
def ngram(string, part_len = 3)<br />
string = string.dup.gsub(/[\s\n　]+/u, &#8220;&#8221;)<br />
strlen = string.split(//u).length<br />
points = []<br />
source = self.gsub(/[\s\n　]+/u, &#8220;&#8221;)<br />
srcarr = source.split(//u)<br />
sourcelen = srcarr.length<br />
return nil if part_len &gt; sourcelen #比較部分文字が作れない<br />
return nil if part_len &gt; strlen #比較対象文字より短いと比較できない<br />
[string, source].each {|cmpstr|<br />
counter = 0.0<br />
(0..(sourcelen &#8211; part_len)).each{|start|#比較文字開始位置ポインタのループ<br />
part = srcarr[start, part_len].join(&#8220;&#8221;) # 比較対象文字<br />
hit = cmpstr.scan(/#{Regexp.quote(part)}/).size<br />
counter += hit<br />
}<br />
points &lt;&lt; counter<br />
}<br />
points.shift / points.shift #比較文字の類似度 ÷ 自分自身の類似度（基準値）<br />
end<br />
end<br />
[/ruby]</p>
<p><a rel="noopener" target="_blank" href="http://search.cpan.org/dist/String-Trigram/Trigram.pm">String::Trigram<span class="fa fa-external-link external-icon anchor-icon"></span></a>の動作を見ていないので同じ挙動かどうかは確認できていませんが、String自身と比較対象文字がどれくらい似ているのかを百分率で返します。<br />
何文字ずつ比較するかを設定できますが、比較できないような長さを設定するとnilが返ります。</p>
<p>動作確認として、上の<a rel="noopener" target="_blank" href="http://blog.livedoor.jp/techblog/archives/64737211.html">livedoor Techブログ<span class="fa fa-external-link external-icon anchor-icon"></span></a>さまで比較している文字列を使って実行してみましょう。</p>
<blockquote><p>&#8220;ライブドアでブログを書く&#8221;.ngram(&#8220;ブログをライブドアで書く&#8221;)<br />
=&gt; 0.6<br />
&#8220;梅雨（ばいう、つゆ）とは、北海道と小笠原諸島を除く日本や朝鮮半島南部、華南や華中の沿海部や台湾において見られる特有の気象で、5月から7月半ばにかけて毎年めぐってくる、雨の多い期間のこと。梅雨の時季が始まることを梅雨入り、梅雨が終わって夏になることを梅雨明けと言い、日本では、各地の地方気象台・気象庁が梅雨入り・梅雨明けの発表をする。&#8221;.ngram(&#8220;「梅雨」北海道と小笠原諸島を除く日本において見られる特有の気象で、5月から7月半ばにかけて毎年めぐってくる、雨の多い期間のこと。梅雨に入ることを梅雨入り、梅雨が終わって夏になることを梅雨明けと言い、日本各地の地方気象台・気象庁が梅雨入り・梅雨明けの発表をする。&#8221;)<br />
=&gt; 0.733333333333333</p></blockquote>
<p>長い文字列の結果がちょっと違いますね。。。<br />
念のため、もう少し比べてみます。</p>
<blockquote><p>&#8220;鳴かぬなら殺してしまえホトトギス&#8221;.ngram(&#8220;鳴かぬなら鳴くまで待とうホトトギス&#8221;)<br />
=&gt; 0.428571428571429<br />
&#8220;鳴かぬなら鳴くまで待とうホトトギス&#8221;.ngram(&#8220;鳴かぬなら殺してしまえホトトギス&#8221;)<br />
=&gt; 0.4</p></blockquote>
<blockquote><p>&#8220;織田信長は、桶狭間で今川義元を破り、天下統一の足がかりを作った&#8221;.ngram(&#8220;徳川家康は、二度に渡る大阪の陣で豊臣家を滅ぼし、名実共に天下人となった&#8221;)<br />
=&gt; 0.0<br />
&#8220;織田信長は、桶狭間で今川義元を破り、天下統一の足がかりを作った&#8221;.ngram(&#8220;徳川家康は、二度に渡る大阪の陣で豊臣家を滅ぼし、名実共に天下人となった&#8221;, 2)<br />
=&gt; 0.1<br />
&#8220;徳川家康は、二度に渡る大阪の陣で豊臣家を滅ぼし、名実共に天下人となった&#8221;.ngram(&#8220;織田信長は、桶狭間で今川義元を破り、天下統一の足がかりを作った&#8221;)<br />
=&gt; 0.0<br />
&#8220;徳川家康は、二度に渡る大阪の陣で豊臣家を滅ぼし、名実共に天下人となった&#8221;.ngram(&#8220;織田信長は、桶狭間で今川義元を破り、天下統一の足がかりを作った&#8221;, 2)<br />
=&gt; 0.0882352941176471</p></blockquote>
<p>実用に耐える程度には抽出できているようなので今回はここまでです。</p><p>The post <a href="https://freestyle.nvo.jp/archives/919">N-gramで文字列の類似度を測る</a> first appeared on <a href="https://freestyle.nvo.jp">FreeStyleVision</a>.</p>]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
