easy_fabricator とか作ってみた。

あるいは。

Ruby で動的に class を定義したかった。

twitter 上で何人かにそんなんできるよって言われたんだけど、どうにも伝わらなかった部分。

class を生成したいんじゃなくて、class 構文を使わずに class を定義したい。

なんでかというと

Fabricator は Model 相当の class の名前を Symbol で与えて使うから

ゴニョゴニョしてできたものはこれ。

#! /usr/bin/env ruby
# -*- coding: utf-8 -*-
require 'optparse'
require 'singleton'
require 'rubygems' unless defined? ::Gem
require 'fabrication'
class EasyFabricator
class Configure
include Singleton
def initialize
@_fields = nil
@_fab = nil
end
def fields
if block_given?
@_fields = yield
else
@_fields
end
end
def fab( &block )
if block_given?
@_fab = block
else
@_fab.call if @_fab
end
end
end
def self.configure(&block)
block.call(Configure.instance)
end
def initialize
@num = 1
@format = 'csv'
@config = Configure.instance
end
attr_reader :config
def run
args.parse!( ARGV )
if ( file = ARGV.shift and File.exist?( file ) )
load file
Object.const_set( 'Model', Struct.new( *config.fields ) )
config.fab
send( "output_#{@format}" )
else
puts args
end
end
def output_csv
require 'fastercsv' if RUBY_VERSION < '1.9'
puts FasterCSV.generate { |csv|
csv << config.fields
}
puts FasterCSV.generate { |csv|
@num.times {
c = Fabricate.build( :model )
csv << config.fields.map { |field|
c[field]
}
}
}
end
def output_yaml
$KCODE = 'u' unless defined? ::Encoding
puts (1..@num).to_a.map { |id|
record = Fabricate.build( :model )
hash = {}
record.each_pair { |k, v|
hash[k.to_s] = v
}
to_yaml( id => hash ).sub( /--- \n/, '' )
}
end
def args
OptionParser.new { |opt|
opt.banner << " fabricator"
opt.on( '-n', '--num NUM ( default 1 )' ) { |num|
@num = num.to_i if num =~ /\A[0-9]+\z/
}
opt.on( '-y', '--output-yaml' ) {
@format = 'yaml'
prepare_yaml
}
opt.on( '-c', '--output-csv ( default )' ) {
@format = 'csv'
}
}
end
private
def prepare_yaml
begin
require 'ya2yaml'
rescue LoadError
require 'yaml'
end
class << self
if ( defined? Ya2YAML )
def to_yaml( obj )
obj.ya2yaml
end
else
def to_yaml( obj )
obj.to_yaml
end
end
end
end
end
if ( __FILE__ == $0 )
EasyFabricator.new.run
end

具体的に困ったこと、解決したことは何か

  • Object.const_set( NAME, classobj ) で好きなタイミングで class 定義できる
    • Klass = な書き方はメソッドの中では不可能
  • fabrication の DSL はちょっと注意が必要

例えば open や catch とかって attribute を用意してしまうと困る。

Fabricator( :model ) do
  open  { ... }
  catch { ... }
end

って書き方になるんだけど、これは通常のメソッド呼び出しになるので定義できない。

回避方法あるのかなぁ。あったら嬉しいんだけど。ダミーデータ用のツールのために元の名前に制限があったらちょっと本末転倒だよね。

PukiWiki 中身消えちゃったように見える問題再現

うちのサーバでも 4.4.2 に上げたら再現したorz 4.4.2 + 1.4.4 はアウトってことね。

そうかい分かったよ、とりあえず PukiWiki 1.4.6 のカスタマイズするよ。常時使ってるものに影響が出ちまったらさすがにやるしかあるまい。

やっぱやめた。どうもファイルの存在が分かってないみたいだなぁとは思っていたのでちょっと眺めてみたら、ページ名からファイル名を取得する encode() に使ってる unpack() で返ってくる値が変わってしまっていた。

CVS Repository - log - SourceForge: pukiwiki/pukiwiki/lib/func.php

を参考に、func.php を

246c246
<       return ($key == '') ? '' : strtoupper(join('', unpack('H*0', $key)));
---
>       return ($key == '') ? '' : strtoupper(bin2hex($key));
252c252
<       return ($key == '') ? '' : substr(pack('H*', '20202020' . $key), 4);
---
>        return ($key == '') ? '' : pack('H*', (string)$key );

にすれば ok っぽい。

ircd-hybrid の 7.2.0 と X-Chat が相性悪い

ircd-hybrid を何の気なしに上げたら

Server load is temporarily too heavy.

ってメッセージがじゃんじゃか出てくるようになった。最初は裏でコンパイルとかしてるから重たいのか?とか呑気なことを考えてたんだけど、調べてみると X-Chat が定期的に /WHO を投げてるのがよくないとかなんとか。snapshot ではもう直ってるから数日から数週間で 7.2.1 が出れば解決じゃないかみたいな話が出てたのが昨年末。まだ 7.2.1 は出ない。

irc クライアント変えれば問題ないのは確認したけど、気持ちよくない(というか新しいソフトいろいろ調べるの面倒でやだ)ので portdowngrade した。すげー便利だな、これ。

初バリウム

健康診断を受けてきた。

噂のバリウムに初挑戦。うわーと思ったがなんてことなかった。炭酸ガスを発生する薬(?)を飲んでバリウムを飲むんだけど、ビール飲んだあとにおいしくもないシェイクを飲むようなもので、期待していたようなつらい体験ではなかった。確かに腹は張るけどまったくどーってことない。

むしろ台に乗せられて身体をぐるんぐるん回すのがびっくりした。なんか右向いてって言われたりあお向けになってって言われたりするんだけど、どっちが何だが混乱して悩んでしまう。別にひっくり返っても右は右なのにね。

Ruby のドキュメント、Python のドキュメント、PHP のドキュメント

Pythonのマニュアルは、Rubyのリファレンスマニュアルより、ずっと良い

Python のマニュアルは量が多いのは分かっているけど真面目に見たことないのでなんとも言えない。ただ、Ruby のリファレンスマニュアルがなんだか微妙だという印象は強い。まつもとさんはまぁまぁだと思っているみたいだけど、個人的には「リファレンスマニュアル

  • 逆引き Ruby」でまぁまぁかなと思っている。

とにかくリファレンスマニュアルは記述が質素すぎて自分のほしい情報への取っ掛かりにしにくく、Namazu で検索してもタイトルでは意味がまったく分からないことが多いような気がする。ページをもう少し細かく分けた方がいいのかもしれない。1PHP のマニュアルのようにものすごく大量なのもそれはそれで確かに扱いにくいんだけど、検索に関して言えば PHP の方はほぼ目的のものが一発で見つかるので助かる。

あと凡例のページを用意してほしいかな。ソースコード内で意味を持ちそうな記号を説明用の記号として使っているので、どこからが説明でどこまでコードなのか判別しにくい。あるいはソースコードをハイライトする RWiki のプラグインのようなものがあればよいのかもしれないけど。よくサンプルコードを見て首をひねってしまう。

Ruby に慣れていれば「こんな記号に意味はない」と一発で分かるんだろうけど、そういう人はそんなにリファレンス見ないと思うんだな。その辺の書き手と読み手の意識のずれが Ruby 関係のドキュメントをよりよくしようとする際のカギなのかもしれない。

  1. その後、2005-02 に 1.8.2 の HTML マニュアルがダウンロードできるようになり、以前より検索精度が高くなったように感じる。HTML ソースなどを詳細に眺めたわけではないが、少なくともページタイトルを見ても意味がよく分からないということは減ったと思う。 

About

例によって個人のなんちゃらです

Recent Posts

Categories

Tool 日々 Web Biz Net Apple MS ことば News Unix howto Food PHP Movie Edu Community Book Security Text TV Perl Ruby Music Pdoc 生き方 RDoc ViewCVS CVS Rsync Disk Mail FreeBSD Cygwin PDF Photo Zebedee Debian OSX Comic Cron Sysadmin Font Analog iCal Sunbird DNS Linux Wiki Emacs Thunderbird Sitecopy Terminal Drawing tDiary AppleScript Life Money Omni PukiWiki Xen XREA Zsh Screen CASL Firefox Fink zsh haXe Ecmascript PATH_INFO SQLite PEAR Lighttpd FastCGI Subversion au prototype.js jsUnit Apache Trac Template Java Rhino Mochikit Feed Bloglines CSS del.icio.us SBS qwikWeb gettext Ajax JSDoc Rails HTML CHM EPWING NDTP EB IE CLI ck ThinkPad Toy WSH RFC readline rlwrap ImageMagick epeg Frenzy sysprep Ubuntu MeCab DTP ERD DBMS eclipse Eclipse Awk RD Diigo XAMPP RubyGems PHPDoc iCab DOM YAML Camino Geekmonkey w3m Scheme Gauche Lisp JSAN Google VMware DSL SLAX Safari Markdown Textile IRC Jabber Fastladder MacPorts LLSpirit CPAN Mozilla Twitter OpenFL Rswatch ITS NTP GUI Pragger Yapra XML Mobile Git Study JSON VirtualBox Samba Pear Growl Mercurial Rack Capistrano Rake Win RSS Mechanize Sitemaps Android JavaScript Python RTM OOo iPod Yahoo Unicode Github iTunes God SBM friendfeed Friendfeed HokuUn Sinatra TDD Test Project Evernote iPad Geohash Location Map Search Simplenote Image WebKit RSpec Phone CSV WiMAX USB Chrome RubyKaigi RubyKaigi2011 Space CoffeeScript Nokogiri Hpricot Rubygems jQuery Node GTD CI UX Design VCS Kanazawa.rb Kindle Amazon Agile Vagrant Chef Windows Composer Dotenv PaaS Itamae SaaS Docker Swagger Grape WebAPI Microservices OmniAuth HTTP 分析基盤 CDN Terraform IaaS HCL Webpack Vue.js BigQuery Middleman CMS AWS PNG Laravel Selenium OAuth OpenAPI GitHub UML GCP TypeScript SQL Hanami Document SVG AsciiDoc Pandoc DocBook Develop Jekyll macOS Node.js Vite Heroku Transformer AI Data Cloud Wasm