トップ 最新 追記

Route 477



2007-02-06

[prog] C#2.0時代のゲームプログラミング(49) 〜 delegateを用いたcontinuation

C#の無名delegate(クロージャっぽいやつ)とCPS変換の話。

11月ごろから書こうと思いつつ放置しているネタに「call/ccを使ってRPGのイベントを実装する(した)」という話が あるんだけど、そうか、実は

  1. call/ccでやる
  2. yieldでやる
  3. CPS変換でやる

という3つの似た選択肢があるんだな。2とか3だとどういうコードになるんだろ…。あとで考える。


2007-02-05

[ruby] RubyでHTMLとWebを操作するためのライブラリ、HpricotとWWW::Mechanize

今日は、RubyでWebサイトを解析するときに強い味方となるライブラリ、HpricotとWWW::Mechanizeを紹介します。

どちらも非常に強力なので、覚えておいて損はないよ!

以下ではまずHpricotでHTMLを解析・編集する方法について解説します。 次に、「はてなダイアリーの自動更新」を例にWWW::Mechanizeの使い方を解説します。

Hpricot

HpricotはHTMLを解析するためのライブラリです。

例えば「あるページのリンクだけを全部抜き出したい」と思ったとき、どうしますか?scrAPIを使う?でもscrAPIはやっぱり ちょっと使いたいだけなのにパーザ(Scrape)用のクラスを定義するのが面倒なんだよね!

Hpricotなら、たったこれだけで解析完了です。

require 'hpricot'
require 'open-uri'

doc = Hpricot( open("http://www.kmc.gr.jp/").read )

(doc/:a).each do |link|
  puts "#{link.inner_html} → #{link[:href]}"
end

HTMLを読み込むには「Hpricot()」という関数にHTMLデータの文字列を与えればOK。 例ではOpenURIを使ってネットから取得しています。

タグを検索するには、読み込んだデータの「/」というメソッドにシンボルか文字列を渡します。

tableタグを全て探す
doc/:table
<div id="hoge">を全て探す
doc/"div#hoge"
<span class="moge">を全て探す
doc/"span.moge"

CSSに慣れている人なら気付いたと思いますが、2番目、3番目の書き方は「CSSセレクタ」と呼ばれるものです。 Hpricotでは他にもさまざまなCSSセレクタを 使用することができます。*1

<table id="list">の中のtdタグを全て探す
doc/"table#list td"
"index.cgi?"から始まるリンクを全て探す
doc/"a[@href^='index.cgi?']"
テキストに"new"という文字列が入っているリンクを全て探す(※version 0.5以降)
doc/"a[text()*='new']"

上の例はどれも「〜なタグを全て探す」でしたが、条件に当てはまるものを一つだけ取り出したいこともありますよね。 そんな時はdoc.at()が使えます。

一番最初のリンクを探す
doc.at(:a)
ElementsとElem

タグ一覧はHpricot::Elementsのインスタンスになります。これはArrayのサブクラスなので、 firstで最初の要素を取り出したり、eachでループを回したり、find_allで条件に合うものだけ抜き出したりできます。

またそれぞれのタグはHpricot::Elemのインスタンスになります。

Elemには以下のようなメソッドが定義されています。

  • attributes : 属性一覧
  • ["href"] : 属性hrefの値を得る
  • name : タグ名
  • parent : 親要素
  • containers : 子要素(タグのみ)
  • children : 子要素(テキストやコメントも含む)
  • css_path : その要素のCSSパス
  • previous_sibling, next_sibling : 隣の要素(タグのみ)
  • previous_node, next_node : 隣の要素(テキストやコメントも含む)
  • each_child{|elem| ..} : 子要素について繰り返す
  • inner_html, inner_text : 内部のHTML, 内部のテキスト
  • to_html : そのタグも含めたHTML
  • to_original_html : そのタグも含めたHTML(なるべく元のHTMLと同じように出力する)
  • to_plain_text : 読みやすいテキストに整形する

実はElemやElementsにも「/」や「at」が定義されているので、「/」による検索結果に対し「その中をさらに探す」なんてこともできます。

例:

divタグの中のリンクを全て探す
doc/:div/:a
各divタグの中の最初のリンクを探す
(doc/:div).each do |div|
  first_link = div/:a
end
HTMLに変更を加える

Hpricotの凄いところはHTMLへの変更もサポートしている点です。 linkをあるリンクタグだとすると、link.inner_html に文字列を代入すると中身のHTMLが変更されたり、 link[:href] = "foo.html" とするとリンク先が"foo.html"になったりします。

これらの変更は、to_htmlなどが生成するHTMLに反映されます。 例えば「サーバ移転したのでexample.jpへのリンクをexample.orgに直したい」という場合は、

doc = Hpricot(ARGF.read)
(doc/:a).each do |link|
  link[:href].gsub! %r(http://example.jp/), "http://example.org"
end
print doc.to_html

という感じで簡単にフィルタスクリプトを書くことができます。

変更系のメソッドには以下のようなものがあります。

  • ["href"]= : 属性hrefの値をセットする
  • inner_html= : 内部のHTMLをセットする
  • name= : タグ名をセットする
  • children= : 子要素をセットする
余談

「/」とか個性的なメソッド名が多いHpricotですが、実は「もっと普通の名前」も用意されています。 例えば「/」には「search」という別名がありますし、 HTMLの読み込みは Hpricot.parse(html) とも書けます。 でもやっぱり短い方を使っちゃうんだよね…!(便利だから)

WWW::Mechanize

WWW::Mechanizeは、Webサイトへのアクセスを自動化するためのライブラリです。

例えばはてなダイアリーに日記を投稿するスクリプトを書くとしましょう。 Net::HTTPだとまず投稿用のURLを調べて、フォームタグの名前を調べてPOSTして、あれ認証ってどうやるんだっけ…?なんて いろいろなことを考えないといけませんが、WWW::Mechanizeを使えば「普段ブラウザを操作するのと同じような感覚で」 スクリプトを書くことができます。

では、ブラウザから日記を書くときの手順を思い出してみましょう。

  1. http://d.hatena.ne.jp/(ユーザid)/ を開く
  2. おおっと、ログインしてなかった。右上の「ログイン」をクリックする
  3. ユーザー名とパスワードを入力し、「ログイン」を押す
  4. 「自動でページを移動しています(移動しないときはこちらのリンクを…)」
  5. 「日記を書く」をクリック
  6. textareaに日記本文を入力し、「この内容を登録する」を押す

WWW::Mechanizeなら、これをそのままスクリプトに落とすことができます。

(1) http://d.hatena.ne.jp/(ユーザid)/ を開く
 require 'mechanize'
 require 'kconv' #あとでUTF-8を扱うので

 agent = WWW::Mechanize.new
 diary_page = agent.get("http://d.hatena.ne.jp/(自分のはてなid)/")

newでインスタンスを作って、getでWebページを取得しています。簡単ですね。

(2) おおっと、ログインしてなかった。右上の「ログイン」をクリックする
 login_link = diary_page.links.text("ログイン".toeuc)
 login_page = agent.get(login_link.href)

diary_page.linksでページ中のリンク一覧が取得できます。ここでは、全てのリンクの中から テキストが"ログイン"に一致するものを探しています。

login_linkはMechanize::Linkのインスタンスで、login_link.hrefでURLが得られます。agent.getにこのURLを渡してログインページを開きましょう。

(3) ユーザー名とパスワードを入力し、「ログイン」を押す
 login_form = login_page.forms.first
 login_form['key'] = "(ユーザ名)"
 login_form['password'] = "(パスワード)"
 redirect_page = agent.submit(login_form)

login_page.formsでformタグの一覧が取得できます。ログインページにはformが一つしかないので、firstで最初のformを選んでいます。

次の行では、<input name="key" ...> というインプットボックスにユーザ名を入力しています。 パスワードも同様に入力します。

agent.submitにこのフォームを渡すとフォームの内容が送信され、送信結果のページが返ってきます。

(4) 「自動でページを移動しています(移動しないときはこちらのリンクを…)」
 diary_link = redirect_page.links.text("こちら".toutf8)
 diary_page = agent.get(diary_link.href)

ログインすると、おなじみの「移動しないときはこちらのリンクを…」というリダイレクトページになります。 WWW::Mechanizeにはリダイレクトを自動で追跡してくれる機能がある…のですが、このリダイレクトページは200 OKなので 自動追跡が効きません(´・ω・`) 仕方がないので、手動でリンクをクリックしましょう。 またこのページはさっきとちがってUTF-8なので、"こちら"もUTF-8に変換しておきます。

(5) 「日記を書く」をクリック
 edit_link = diary_page.links.text("日記を書く".toeuc)
 edit_page = agent.get(edit_link.href)

ここまで来たらあと一歩です。"日記を書く"のリンクを探し、クリックします。

(6) textareaに日記本文を入力し、「この内容を登録する」を押す
 edit_form = edit_page.forms.name("edit").first
 edit_form["body"] += "\n*Rubyから日記を更新してみるテスト。"
 ok_button = edit_form.buttons.name("edit")
 agent.submit(edit_form, ok_button)

さあ、いよいよ日記の書き込みです。編集画面には複数のフォームがあるので、edit_page.form("edit") で最初の <form name="edit" ...> というタグを見つけています。また、このフォームには「確認する」と「登録する」という複数のsubmitボタンがあるので、 登録ボタンを探してsubmitに渡しています(「こっちのボタンを押してください」という意味です)。

http://d.hatena.ne.jp/(はてなid)/ を見てみてください。新しい日記が書き込まれましたか?:-)

WWW::Mechanizeではこのように、ブラウザを操作するような感覚でスクリプトを書くことができます。

簡易リファレンス

pageには以下のようなメソッドがあります。

  • links : リンク(aタグ)一覧
  • forms : formタグ一覧
  • form("foo") : name="foo"である最初のformタグ
  • title : ページタイトル(titleタグの中身)
  • header : HTTPのレスポンスヘッダ
  • root : ページの内容を表すHpricotドキュメント

linksやformsはMechanize::Listのインスタンスを返します。これはArrayのサブクラスなので、配列のように扱うことができます。 また簡便のため、「hrefが"index.cgi"であるものを全て探す」という操作を links.href("index.cgi") のように書けたり、 「name属性が"hoge"であるものを全て探す」という操作を forms.name("hoge") と書けるようになっています。

linkには以下のようなメソッドがあります。

  • href : リンク先のURL
  • text : aタグの中身のテキスト
  • node : aタグを表すHpricot::Elem
  • click : リンクをクリックし、結果のページを返す (newpage = agent.get(link.href) が、 newpage = link.click のように書ける)

formには以下のようなメソッドがあります。

  • []=("foo", "bar") : name="foo" であるフィールドに値"bar"をセットする
  • submit : フォームをsubmitし、結果のページを返す (newpage = agent.submit(form) が、 newpage = form.submit のように書ける)

より詳細なリファレンスはWWW::Mechanize 日本語リファレンスを参照してください。

インストール

さて、そろそろ実際に使ってみたくなったでしょうか?:-) rubygemsをインストール済みなら、

gem install hpricot
gem install mechanize

と、簡単なコマンドでインストールできます。

  • 前述のとおりmechanizeはhpricotに依存しているので、 mechanizeを入れればhpricotは自動的に入ります。
  • Hpricotはつい最近version 0.5が出たので、昔インストールしたことがある人もアップデートをお勧めします。
  • Hpricotは途中でUnix版を入れる(ruby)かWindows版を入れる(mswin32)か聞かれるので、自分の使っている方を選んでください。

rubygemsを使っていない人はアーカイブをダウンロードし、中に入っているinstall.rbを実行すればOKです(たぶん)

まとめ

本稿では、RubyでWebから情報を得るときに役立つ2つのライブラリ、HpricotとWWW::Mechanizeを紹介しました。

これらを使うことで、HTMLのスクレイプやWebアクセスの自動化など今まで「面倒そうだなぁ」と思っていた処理が非常に簡単に書けるようになります。 Webでの情報収集を自動化したくなったとき、この2つのライブラリのことを思い出してもらえれば幸いです。

*1 さらにHpricotではXPathも使える…のですが、たいていはCSSセレクタで間に合うと思います。

[ruby][hiki] HikiReload

WWW::Mechanizeの使用例として、「テキストファイルが保存されたら自動的にWikiを更新する」というスクリプトを載せておきます。 上の記事もこのスクリプトを使って下書きしましたが、自分のお気に入りのエディタを使えるので非常に便利でした:-)

フォームタグを名前で探しているのでHiki限定ですが、他のWikiエンジンへの対応も難しくないと思います。 ぜひチャレンジしてみてください。

#!/usr/bin/env ruby
require "mechanize"

class HikiReload
  POLL_SECONDS = 3

  def initialize(url)
    @agent = WWW::Mechanize.new
    @url = url
  end

  def poll(path)
    loop do
      mtime = File.mtime(path)
      while File.mtime(path) == mtime
        sleep POLL_SECONDS
      end
      puts "file #{path} changed.."
      submit(File.read(path))
      puts "submitted."
    end
  end

  def submit(str)
    editpage = @agent.get(@url)
    form = editpage.forms.first
    form.contents = str
    result_page = @agent.submit(form, form.buttons.name("save"))
    puts result_page.root.to_html
  end
end

url, file = "http://example.jp/hiki/?c=edit;p=FrontPage", "temp.txt"

HikiReload.new(url).poll(file)

使い方

  1. hikireload.rbという名前で保存(urlは自分のWikiに書き換える)
  2. temp.txtに下書きを書く
  3. ruby hikireload.rbで起動
  4. temp.txtを編集すると、エディタで保存するたびにWikiが更新される

エディタでWikiを編集するためのソフトウェアはemacsのhiki-modeなどいくつかありますが、このアプローチだと エディタを選ばない(emacsでもVimでもxyzzyでも秀丸でもなんでも使える)のが利点だと思います。

本日のツッコミ(全3件) [ツッコミを入れる]

 [すごいですね。ruby だんだん好きになっちゃいましたよ。 ruby中毒になった感じ]

ザッピング運営事務局 [※このコメントは、 ザッピングをご利用して頂いているユーザー様を対象にお送りしております。 既にタグを変更して頂いて..]

ケムス [良く勉強になりました。  ありがとうございます。]


2007-01-31

[prog] anarchy golf始まったな

おおお格好いい!

というわけでテストも兼ねて、Hello, wolrd!の投稿されてない 言語をひととおり埋めてみました。

最初の方は真面目にやってたんですが…Adaあたりからだんだん分からなくなって…、 なんというかその、Wikipediaは便利ですね(おい!)

あと残り4つ。

  • Io : なんかtimeoutになってしまう ("Hello, world!" print であってますよね?)
  • whitespace : なんか何も出力されなくてfailedになる
  • sed : わかんないんです(><)
  • x86(exe) : アセンブラ書けないんです(><)*1

(2/2追記:ioとwhitespace(とbefunge)については修正が入ったようです。ありがとうございます。)

*1 サイズが10KBを越えてはいけないのである


2007-01-29

[junk] あーてすてす

4797336021

[prog] flapjax

d.y.d.より。JavaScript で Reactive Programming らしい。熱い。

Reactive Programmingというのは、 x = f(a); と書いておくとaの値が変化したときに xを勝手に再計算してくれるようなシステムである(と思う)。 GUIとかアニメーションとかに向いているらしい。*1

*1 ゲームにも有効なんだろうか?

[prog] Circular Program

同じくd.y.d.より。 「木を1回traverseするだけで全てのノードを最小値に置き換えるとかいうのに使う技」らしい。

同じような話を見た覚えがあるなあ、と思って「今日の一行」を見直してみたのだが、 素朴な実装は分かったけど 回答例の方は技巧的でよく分からん^^; (図に描いてみないと…)

疑問:

  • Circular Programを普通の形式に直すと何が嬉しいのか?
  • 回答例のやり方はCircular Programに含まれる?

2007-01-25

[ruby] ホワイの(感動的)Rubyガイド

読んだ。なんというシュール…。

Tシャツが欲しくなった。

[junk] PS3とWiiの大きさに関する重大な事実

並べてみるとそれほど差はない

むしろWiiの方が大きく感じられる

PS3とWii(の箱)

#冗談ですよ


2007-01-21

[kmc] おおさと杯

部内の若者向けプログラミングコンテスト、通称「おおさと杯」の第3回が行われました。

基本的にICPCのような感じ(風船マークもあるよ!)で3時間6問なんですが、言語はC系だけではなく、RubyとHaskellも 使えるという充実ぶり。

僕はせっかくなのでRubyで参加しましたが、問題を読み間違ったりなんだりで結局3問しか解けず…駄目駄目ですね。 とはいえ、Rubyでコンテスト的なプログラムを書くのもなかなか新鮮で楽しかったです。次回はHaskellか!?(入力が一番大変そうだ…^^;)

[spoj] Sphere Online Judge

で、Rubyとかが使えるOnline Judgeとかないよねーという話をしたら、Sphere Online Judge(SPOJ) というサイトがあると教えてもらいました。

uvaPKUのような感じで、使用可能な言語は なんと驚きの35種類!

C (gcc 4.0.0-8)
C99 strict (gcc 4.0.0-8)
C++ (g++ 4.0.0-8)
Pascal (gpc v20030830)
Pascal (fpc 2.0.4)
Java (j2se jdk 5.0)
Nice (nicec 0.9.6)
JAR (j2se jdk 5.0)
C# (mcs 1.0.1)
Nemerle (ncc 0.2.1)
Smalltalk (gst 2.1.7)
Assembler (nasm 0.98.38)
Algol (a60 0.20a-4)
Fortran (g77 3.3.3)
ADA 95 (gnat 3.15p)
Bash (bash 2.05b-15)
Perl (perl 5.8.3)
Python (python 2.4)
Ruby (ruby 1.8.1)
Lua (lua 5.0.2)
Icon (iconc 9.4.2)
Pike (pike 7.4.35)
PHP (php 4.3.8-9)
Scheme (guile 1.6)
Scheme (qobi 0.9+0.10a)
Common Lisp (gcl 2.6.5)
Common Lisp (clisp 2.33.2)
Haskell (ghc 6.4.1)
Ocaml (ocaml 3.08.1)
Clips (clips 6.21)
Prolog (swipl 5.2.7)
Whitespace (wspace 0.3)
Brainf**k (bf2c)
Intercal (ick 0.24)
Text (pure text)

C/C++/C#/Java等の基本的なところからPerl/Python/Ruby/Pike/Luaのようなスクリプト言語、Lisp,Scheme/Haskell/Ocamlのような関数型言語から Bash/nasm/Whitespace/Brainf**kのような変り種まで幅広く取り揃えられています。

…しかし最後の「Text」ってのはどういう言語なんでしょうか? 期待されるoutputをすべてそのまま予想したらAccept?

[spoj] SPOJをネタにRaccを使ってみるテスト

1. TEST

こりゃー簡単ですよね。インタプリタ走らすまでもなく解けるぜ!

…と思ったら改行の処理を忘れて1miss _|‾|○

2. PRIME1

require 'mathn' してPrime#each使ったら一発じゃね!? と思ったのですが、TLE。もうちょっと真面目にやらないと駄目なようです。 ああ、難易度順に並んでるというわけではないのね。

3. SBSTR1

文字列Aに文字列Bが含まれているかを判定する問題。これこそString#include?一発では?と思ったら…

Please note, that the solution may only be submitted in the following languages: Brainf**k, Whitespace and Intercal.

ちょwww

4. ONP

四則演算+αの式を逆ポーランド記法に直す問題。要するにパーサ書けばいい、んですが…

せっかくだから俺はこの青のRaccを使うぜ!

いや、いいんですよ!Raccの練習だから!

gotokenさんの記事 (今は亡きCマガ…;涙) を見つつ、onp.y を書いてみる。

# exp = exp (+,-,*,/,^) exp |
#       '(' exp ')' |
#     = IDENT
class OnpParser
  prechigh
    left '^'
    left '/'
    left '*'
    left '-'
    left '+'
  preclow
rule
  exp : exp '+' exp { result += "#{val[2]}+" }
      | exp '-' exp { result += "#{val[2]}-" }
      | exp '*' exp { result += "#{val[2]}*" }
      | exp '/' exp { result += "#{val[2]}/" }
      | exp '^' exp { result += "#{val[2]}^" }
      | '(' exp ')' { result = val[1] }
      | IDENT
      ;
end

こんな感じかね?

あとスキャナ部分も書かんといかんらしいので、

require 'onp.tab.rb'
class OnpParser
  def parse(str)
    scan(str)
    do_parse
  end

  private
  def scan(str)
    @q = []
    until str.empty?
      case str
      when /\A\s+/
        # skip
      when /\A([a-z])/
        @q.push [:IDENT, $1]
      when /\A./
        # +-*/^()
        c = str[0].chr
        @q.push [c, c]
      end
      str = $'
    end
    @q.push [false, '$end']
  end

  def next_token
    @q.shift
  end
end

gets
while line=gets
  puts OnpParser.new.parse(line.chomp)
end

こんな感じで。要するにパーザクラスのnext_tokenメソッドで [トークンの種類、トークンの中身] という配列をひとつずつ返せばいいらしい。 上では記事の例と同じように、scanメソッドで一気に全てのトークンを切り出しています。

というわけでONPは解けた、と思う、んですが…

submitしたらNZEC(non-zero exit codeらしい)だったよ!

require 'racc/parser' だけでもNZECになるので、どうもraccは使えない予感。

…ですよねー(´・∀・`)


2007-01-19

[kmc] fonのルータが発送されたようです

この度は、フォン・ジャパン株式会社をご利用いただき、誠にありがとうございました。
2007年1月7日にご注文をいただきました商品を、2007年1月19日に発送いたしました。
        ↑                                           ↑

遅いよ^^;;;;

あやうくもう一個申し込むところだったぜ…!

[softs] デスクトップがどっかからダウンロードしたpdfで一杯なんだが

ファイル名が020010.pdfとか、msg4001.pdfとかでどれがどれやら…。

かといってダウンロードするときにいちいち意味のあるファイル名付けるのも面倒なんですよね。

自動で、配布元のURLとページタイトル*1をファイル名に付加してくれる ソフトがあると嬉しいかも。greasemonkeyでできたりせんかな。

*1 セクションタイトルもあるとなおいい

本日のツッコミ(全3件) [ツッコミを入れる]

hanya [僕のデスクトップにはあと4つぐらいしかファイルを置くスペースがありません!]

yhara [1.新しいフォルダを作る 2.デスクトップ上のアイコンを全部突っ込む 3.すっきり!]

mts [発想を逆転して、pdfを簡単に閲覧できるpdf explorerとかどうかな? http://www.forest...]


2007-01-18

[softs] Xうごいた

(前回までのあらすじ) scim-anthyのためにVMWare Player上のDebianをtestingに上げたyharaだったが、etchではXがx.orgに 変わっているという罠が!xinitしてもエラーで起動しないXをyharaはなんとかできるのか!?

結論から言うと

apt-get install xserver-xorg-input-vmmouse
apt-get install xserver-xorg-video-vmware

して、dpkg-reconfigure xserver-xorgしたらなんか動いた。選択肢を忘れちゃったので何の参考にもならん。すいません…。 基本的にわかんないとこはスルー(Enter)もしくは"vmware"とか。

参考:

ちなみにscimの起動にはまだ成功していません^^;


2007-01-17

[ruby] RubyのWWW::Mechanizeの日本語リファレンス

なんとなくWWW::Mechanizeが使いたくなったので、とりあえずリファレンスを訳してみた。

続きを読む

[tDiary] 褒めてはいけない

同じパターンのコメントスパムが一杯来るので、設定画面で「(Good|Cool) site. Thank(s| you)!!」みたいなのをはじくことにした。

具体的には

[\w\s]+ site\. Thank[\w\s]+

というパターンがコメント本文に含まれていると投稿できません。これ以降、このサイトを褒めたいときは別の表現を使用してください :-)

[rskit] 褒められた!

Ruby は...、なんだろう?とりあえず今弄ってる奴の元になったサンプルが素晴らしく理解しやすい&弄りやすかったというべきだろうか?

[http://d.hatena.ne.jp/isshiki/20070109/p4より引用]

実はあのサンプルの300行に3日くらいかけてたりするので^^; 非常に嬉しいです。 サンプルコードはこれから製作されるゲームに再利用される可能性が高いので気が抜けないですね。 部内でもDown!!のソースとかたまにコピペされてたりするし(※今から参考にするなら断然apple catcherの方がお奨めです)。

まぁプログラミング経験者にとって理解しやすいのと非経験者にとって理解しやすいのはまた違うかも知れません…ということで、 より初心者向けなソース解説をるびまに記事として書かせてもらえることになりました。 1ヵ月後くらいには掲載されると思うので乞うご期待。

あと 他言語から来た人のためのRubyメモ *1は Stringクラスの便利なメソッドについても書こうと思ってたんですが…、放置している間にRuby初心者で無くなってしまった…。 何を書こうと思ってたんだっけなぁ。

鉄は熱いうちに打たんと。

*1 最初は「Ruby初心者のためのTips」という名前だったが、あんまり適切じゃない気がして改名

[ruby] 知らなかった

File.readの実体がIO.readだったなんて!

リファレンスにFile.readの項が無かったんでびっくりした。こんなに良く使うのになぁ。

本日のツッコミ(全2件) [ツッコミを入れる]

isshiki [なんか雑記の一文に反応してくださったのに今更気がつきました。反応遅くなって申し訳ないです。 件のシューティングですが..]

yhara [いえいえ、昨日の晩に書いたところなんで全然遅くないですよ^^; シューティングの方、期待して待ってます。ソースについ..]


2007-01-15

[ruby] exe生成器

RubyスクリプトをExerb化すると、$0への代入がエラーになるようだ。

$0 = "main.rb"
packer.rb:36: $0 not initialized (RuntimeError)

これは仕様?

まぁ、今回は回避可能なんで大丈夫だが。

[ruby] exe生成器(2)

基本部分ができてきた。

  • packer.exe : 設定画面
  • packer.exe --mkexy : exyファイルの作成(内部利用)
  • packer.exe --exerb : exeファイルの作成(内部利用)

という感じで行く予定。

本日のツッコミ(全2件) [ツッコミを入れる]

shinpei@ec4.technowave.ne.jp [> まぁ、今回は回避可能なんで大丈夫だが。 どうやったんですか? 自分もExerbで同じエラーが出たんです。]

yhara [ごめんなさい、全く覚えてないです。 「$0に代入しない」とかだったかも。]