win32/configure.batが生成する Makefileを編集して* ruby19.exeを作るようにしていると ruby-dev:34000 と同じところで止ま
MLのスレ
* configure.batの引数として与える方が人手を介さない分、良さそう。1.8のときに prefixオプシ
最終更新: 2010-03-22T05:44+0900
著者は ActiveScriptRubyの arton氏。
この本が出た当時、Mysterious SyndromeWindows Scripting Host Laboratoryの管理人むたぐち氏が、言語は Rubyであるが、COMや WSHの話題は VBScriptや JScriptと共通だし、他にこんなに突
タイミングを逸していただけなのだ。
Rubyの名前を初めて目にしたのもこの時だ
あくまで目にしていただけで、初めての CGIプログラムはサンプルの多い Perlで書いたし、すぐに嫌気がさして代わりの言語を探したときに Rubyを"再"発見している。そのときに、WSHに親しんでいたことと ActiveScriptRubyの存在が Ruby採用のき
思い出深い一冊ということ。この本を通して、気付かないまま Rubyとすれ違
リストを使うと途端にそこから文章に構造がなくな
HikiDoc(r90)のリストアイテムに文章構造(段落)を持ち込むための変更
*li1-p1\ \ li1-p2A\ li1-p2B *li2
li1-p1
li1-p2A li1-p2B
<ul> <li><p>li1-p1</p> <p>li1-p2A li1-p2B</p> </li> <li>li2</li> </ul>
行末の \ は見落としやすいので *-、**-、***- を、前行のリストアイテムを継続する、という意味にするのはどうだろう。
HikiDoc(r90)のリストアイテムに文章構造(段落)を持ち込むための変更2 (以前の変更からの差分なので順番に適用する必要がある)
* li1-p1 *- *-li1-p2A *-li1-p2B *li2
li1-p1
li1-p2A li1-p2B
<ul> <li><p>li1-p1</p> <p>li1-p2A li1-p2B</p> </li> <li>li2</li> </ul>
なぜ *+ でなく *- にしたんだろう……。
最終更新: 2016-11-12T11:41+0900
Rubyの、括弧を使
irb19> re = /%[Qq]?(?<brace>\{[^\{}]*(?:\g<brace>[^\{}]*)*})/ irb19> strings = %w(%{z}a %{a{b}z}c %{a{b}c{d{e}f}z}g %{{{{}}}z}a %{a{b}c %{z}a}b) irb19> strings.each{|str| p str[re] } "%{z}" "%{a{b}z}" "%{a{b}c{d{e}f}z}" "%{{{{}}}z}" nil "%{z}" => ["%{z}a", "%{a{b}z}c", "%{a{b}c{d{e}f}z}g", "%{{{{}}}z}a", "%{a{b}c", "%{z}a}b"]
どの例も正しい範囲( %{ から z} まで)を切り取
/%[Qq]?(?<brace>\{(?:[^\{}]++|\g<brace>)*})/
若干速い。同じパタ
/%[Qq]?(?<brace>\{(?:[^\{}]+|\g<brace>)*})/
上のものの + が一つ落ちたもの。開き括弧が余分にある文字列を食わせると待てども待てども返
最終更新: 2016-11-12T11:41+0900
テキストエデ
構文ハイライトには興味がなくて、どこかからダウンロ
ところが最近 SHJSをいじ
そのためには鬼車が必要。BREGEXP.dllでは %Q<a<b<c>d<e>f>g> のように入れ子にな
キ
以下、変更点のリスト。(\bの使い方が適当なのでスペ
{ // part of Kernel methods. 'regex': /\b(?:defined\?|Array|Floar|Integer|String|abort|callcc|exec|exit!?|fork|proc|lambda|set_trace_func|spawn|syscall|system|trace_var|trap|untrace_var|warn)\b/g, 'style': 'sh_preproc' },
なくてもいいかな、と思うけど defined?と Kernelモジ
{ 'next': 4, 'regex': /<(?=[\w\/])/g, 'style': 'sh_string' },
正規表現を /</g から変更。<<メソ
{ // Symbol 'regex': /:(?:(?:@@|@|\$)?\w+[\?!]?|\+=?|!=?|~|\*\*=?|-=?|\*=?|\/=?|%=?|<<=?|>>=?|&=?|\|=?|^=?|>=?|<=?|<=>|===?|=~|!~|&&=?|\|\|=?|\.\.|\.\.\.|=)(?=\s|$)/g, 'style': 'sh_string' },
新ル
{ // %!string! 'regex': /%[Qq]?([!-'*-\/:;=?^]).*?\1/g, 'style': 'sh_string' },
新ル残念ながら %Q[]のように括弧を使。対応した。詳しくは下の方。
{ 'regex': /(?:\b(?:alias|begin|BEGIN|at_exit|break|case|do|else|elsif|end|END|ensure|for|if|in|include|loop|next|raise|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield|and|not|or|def|class|module|catch|fail|load|throw)\b|&&|\|\|)/g, 'style': 'sh_keyword' },
ここにはプログラムの流れや定義に関するキ
{ // global variables 'regex': /\$(?:[_&~`'\+\?!@=\/\\,;\.<>\*\$:"]|-?[A-Za-z0-9_]+)/g, 'style': 'sh_type' },
グロ
{ // Constants 'regex': /\b[A-Z]\w+[!\?]?(?=\b|$)/g, 'style': 'sh_function' }, { // Constants 'regex': /\b(?:false|nil(?!\?)|true|self|__FILE__|__LINE__)(?=\b|$)/g, 'style': 'sh_function' },
定数のル
{ 'regex': /[a-z0-9_]+(?:\?|!)/g, 'style': 'sh_normal' },
正規表現を /[A-Za-z0-9_]+(?:\?|!)/g から変更。定数は区別したいじ
{ 'exit': true, 'regex': /$/g },
文字列リテラルの終了条件に上のは必要ない、むしろこれがあることで複数行にまたが
{ // %r(regexp) 'next': 6, 'regex': /%r[\(<\[\{]/g, 'style': 'sh_regexp' }, { // %x(command), %w(array) 'next': 7, 'regex': /%[xWw][\(<\[\{]/g, 'style': 'sh_normal' }, { // %(string) 'next': 8, 'regex': /%[Qq]?[\(<\[\{]/g, 'style': 'sh_string' },
[ { 'exit': true, 'regex': /$/g }, { 'next': 6, 'regex': /[\(<\[\{]/g, 'style': 'sh_regexp' }, { 'exit': true, 'regex': /[)>\]}]/g } ], [ { 'exit': true, 'regex': /$/g }, { 'next': 7, 'regex': /[\(<\[\{]/g, 'style': 'sh_normal' }, { 'exit': true, 'regex': /[)>\]}]/g } ], [ { 'exit': true, 'regex': /$/g }, { 'next': 8, 'regex': /[\(<\[\{]/g, 'style': 'sh_string' }, { 'exit': true, 'regex': /[)>\]}]/g } ],
括弧の対応をチ
%(foo{bar)baz}
こんなのも通る。でも現実的には区別する必要ないよね。HTML断片を組み立てるときに問題がありそう。そしてそういうときにこそダブルク
html << %[<option value="#{h hoge}"] << (selected? ? ' selected="selected">' : '>') << h(hoge) << "</option>\n";
や
上で出した「こんなのも通る」と「や
変更点は20080102p01で。
# for variable interpolation, #{ is not a comment
というコメントを付けて #{}のハイライトル
続きは20080105p01で。
eval(<<__END_OF_TOPLEVEL__,TOPLEVEL_BINDING) module TDiary end __END_OF_TOPLEVEL__
に類する evalは
module ::TDiary end
でいいじ
(行間に、構造に関係しないコ
module TDiary class DefaultIO < IOBase private def restore( fh, diaries ) diary = eval( "#{style( style_name )}::new( headers['Date'], headers['Title'], body, Time::at( headers['Last-Modified'].to_i ) )" )
最後の行はこれ↓で。
diary = style( style_name )::new( headers['Date'], headers['Title'], body, Time::at( headers['Last-Modified'].to_i ) )
anchor_str = @plugin.instance_eval( %Q[anchor "#{@diary.date.strftime('%Y%m%d')}"].untaint )
は
anchor_str = @plugin.anchor( @diary.date.strftime('%Y%m%d' ) ).untaint
で OK。
あえて寝た子を起こすまねをして新たなエラ
@plugin_files.grep(/\/category.rb$/).empty?
のコピペの連鎖のようなものは断ち切りたい。emptyかどうかを知りたいのならマ
not @plugin_files.any?{|pi| /\/category.rb\z/ =~ pi } @plugin_files.find{|pi| /\/category.rb\z/ =~ pi }.nil?
のどちらかで十分です。速度的なもの(なんという婉曲さw)は計
irb(main):044:0> plugin_files = Dir.glob('./*.rb') => ["./a.rb", "./akismet.rb", "./amazon.rb", "./append-css.rb", "./bq.rb", "./calendar2.rb", "./calendar3.rb", "./category.rb", "./comment_mail-qmail.rb", "./comment_mail-sendmail.rb", "./comment_mail-smtp.rb", "./comment_rank.rb", "./counter.rb", "./daily_theme.rb", "./disp_referrer.rb", "./doctype-html401tr.rb", "./dropdown_calendar.rb", "./edit_today.rb", "./footnote.rb", "./gradation.rb", "./gradient.rb", "./hide-mail-field.rb", "./highlight.rb", "./html_anchor.rb", "./image.rb", "./kw.rb", "./list.rb", "./makelirs.rb", "./makerss.rb", "./my-ex.rb", "./my-sequel.rb", "./navi_user.rb", "./number_anchor.rb", "./pb-show.rb", "./ping.rb", "./pingback.rb", "./random_google.rb", "./recent_comment.rb", "./recent_comment3.rb", "./recent_list.rb", "./recent_namazu.rb", "./recent_rss.rb", "./recent_trackback3.rb", "./referer-antibot.rb", "./referer-utf8.rb", "./referer_scheme.rb", "./search_control.rb", "./search_form.rb", "./sn.rb", "./speed_comment.rb", "./squeeze.rb", "./src.rb", "./tb-send.rb", "./tb-show.rb", "./title_list.rb", "./title_tag.rb", "./tlink.rb", "./todo.rb", "./weather.rb", "./whatsnew.rb", "./xmlrpc.rb"] irb(main):045:0> Benchmark.bmbm{|j| irb(main):046:1* j.report('grep'){ 10000.times{ plugin_files.grep(/\/category.rb$/).empty? } } irb(main):047:1> j.report('grep2'){ 10000.times{ plugin_files.grep(/\/category.rb\z/).empty? } } irb(main):048:1> j.report('any?'){ 10000.times{ not plugin_files.any?{|pi| /\/category.rb\z/ =~ pi } } } irb(main):049:1> j.report('find'){ 10000.times{ plugin_files.find{|pi| /\/category.rb\z/ =~ pi }.nil? } } irb(main):050:1> } Rehearsal ----------------------------------------- grep 0.359000 0.000000 0.359000 ( 0.361000) grep2 0.297000 0.000000 0.297000 ( 0.275000) any? 0.109000 0.000000 0.109000 ( 0.104000) find 0.094000 0.000000 0.094000 ( 0.105000) -------------------------------- total: 0.859000sec user system total real grep 0.297000 0.000000 0.297000 ( 0.270000) grep2 0.281000 0.000000 0.281000 ( 0.275000) any? 0.094000 0.000000 0.094000 ( 0.100000) find 0.140000 0.000000 0.140000 ( 0.101000)
最新のプラグイン集のプラグインを全て有効にしたのと同じ状態では any? と findの勝ち。これでは全ての要素を調べる grepがあまりに不利。(ちなみに category.rbが見つからなくて grep同様に配列の最後まで調べた場合、any?と findは grepの二倍強の時間がかか
plugin_filesの要素数を半分の 30にしても any?、findの勝ちだ
irb(main):058:0> plugin_files = plugin_files[0,15] => ["./a.rb", "./akismet.rb", "./amazon.rb", "./append-css.rb", "./bq.rb", "./calendar2.rb", "./calendar3.rb", "./category.rb", "./comment_mail-qmail.rb", "./comment_mail-sendmail.rb", "./comment_mail-smtp.rb", "./comment_rank.rb", "./counter.rb", "./daily_theme.rb", "./disp_referrer.rb"] irb(main):059:0> Benchmark.bmbm{|j| irb(main):060:1* j.report('grep'){ 10000.times{ plugin_files.grep(/\/category.rb$/).empty? } } irb(main):061:1> j.report('grep2'){ 10000.times{ plugin_files.grep(/\/category.rb\z/).empty? } } irb(main):062:1> j.report('any?'){ 10000.times{ not plugin_files.any?{|pi| /\/category.rb\z/ =~ pi } } } irb(main):063:1> j.report('find'){ 10000.times{ plugin_files.find{|pi| /\/category.rb\z/ =~ pi }.nil? } } irb(main):064:1> } Rehearsal ----------------------------------------- grep 0.188000 0.000000 0.188000 ( 0.175000) grep2 0.109000 0.000000 0.109000 ( 0.099000) any? 0.110000 0.000000 0.110000 ( 0.106000) find 0.109000 0.000000 0.109000 ( 0.107000) -------------------------------- total: 0.516000sec user system total real grep 0.125000 0.000000 0.125000 ( 0.096000) grep2 0.094000 0.000000 0.094000 ( 0.094000) any? 0.110000 0.000000 0.110000 ( 0.101000) find 0.125000 0.000000 0.125000 ( 0.105000)
category.rbを含めて 15のプラグインが有効の場合、僅差で any?、findの負け。category.rbを使
なじみがあ
2.2.0までは Ruby 1.6もサポ
* ほんとうに?なんで?
日記を更新すると、TDiary::Config#data_path/category/ 以下の、カテゴリごとに作られるキ
どこのコ
PStore.new(cache_file(c)).transaction do |db| end
に囲まれた部分をすべてコメントアウトしても 21のキ
PStoreは transactionの前後で Marshal::dump の戻り値のサイズと MD5が変化したかどうかを見て、変更があ
原因が何であるにせよサ
読み出し専用であることが予めわか
肝心の Category::Cache#replace_sectionsは transactionの開始前に変更があるのかどうかがわからないので PStore#transaction(true)は使えない。日付の削除が空振りに終わ
# # cache each section of diary # used in update_proc # def replace_sections(diary) return if diary.nil? or !diary.categorizable? categorized = categorize_diary(diary) categories = restore_categories deleted = [] ymd = diary.date.strftime('%Y%m%d') categories.each do |c| PStore.new(cache_file(c)).transaction do |db| db['category'] = {} unless db.root?('category') if categorized[c] and diary.visible? db['category'].update(categorized[c]) else # diary is invisible or sections of this category is deleted db.abort unless db['category'].delete(ymd) deleted << c if db['category'].empty? end end end if !deleted.empty? deleted.each do |c| File.unlink(cache_file(c)) end replace_categories(categories - deleted) end end
* 追記:最近の Ruby(1.8.7だか 1.9.0)は Hashの keyの順序を保存しているみたいだけど。
以下のコ
-2000.step(-10000,-10) do |v| puts v end
n=1990;801.times{p -n+=10}
-1 (26バイト)だからバ
irb(main):115:0> require :benchmark.to_s irb(main):119:0> Benchmark.bmbm{|j| j.report } NameError: uninitialized constant Benchmark::Job::ArgmentError from C:/Program Files (x86)/ruby/lib/ruby/1.8/benchmark.rb:333:in `report' from (irb):119 from C:/Program Files (x86)/ruby/lib/ruby/1.8/benchmark.rb:250:in `bmbm' from (irb):119 from :0 irb(main):120:0>
ArgmentError -> ArgumentError
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/44601
irb(main):001:0> RUBY_RELEASE_DATE => "2006-12-25" irb(main):002:0> "aaa"\ irb(main):003:0* "bbb" => "aaabbb" irb(main):004:0> "aaa"\ irb(main):005:0* %[bbb] NameError: undefined local variable or method `bbb' for main:Object from (irb):5
こういうもんなの? "bbb" と %!bbb! は同じものだと思
'%04d-%02d-%02d'%[2007,12,12] => "2007-12-12"
String#% が呼ばれてるんだよ。
二年近くの長い沈黙を破
まずロ
- instance_variables.each do |v| + instance_variables.each do |v| v = v.to_s;
vにシンボルが渡されて、次の行で v.sub!したときにエラ
if page && !page.empty? - redirect(@cgi, @conf.base_url + @plugin.hiki_url( page ), session_cookie( session.session_id )) + redirect(@cgi, @conf.base_url + @plugin.hiki_url( page ), [session_cookie( session.session_id )]) else - redirect(@cgi, @conf.index_url, session_cookie( session.session_id )) + redirect(@cgi, @conf.index_url, [session_cookie( session.session_id )])
Cookieが session_id=SESSIONIDの形でなく SESSIONIDと key名なしの状態でブラウザにセ
Hiki::Command#cmd_logoutでは同じ引数を [session_cookie(session_id, -1)] としていたので同じように配列にした。
- Digest::MD5::new( s || '' ).hexdigest + Digest::MD5::hexdigest( s || '' )
リフ
when Array - "[\n"+obj.collect{|x| dump_text(x)+",\n"}.to_s+"]" + "[\n"+obj.collect{|x| dump_text(x)}.join(",\n")+"\n]" when Hash - "{\n"+obj.sort_by{|e| e[0].inspect}.collect{|k,v| "#{dump_text(k)} => #{dump_text(v)},\n"}.to_s+"}" + "{\n"+obj.sort_by{|e| e[0].inspect}.collect{|k,v| "#{dump_text(k)} => #{dump_text(v)}"}.join(",\n")+"\n}"
dumpに失敗していた。
原因とな
Ruby-1.8.5p12> [1,2,3].to_s #=> "123" Ruby-1.9.0 20061205> [1,2,3].to_s #=> "[1, 2, 3]"
リフ
to_s self.join($,) と同じです。
と書いてあるから to_sで(ある種の) joinを代用していても仕方ない。
と思
上のエントリで FrontPageの表示とログインまでや
'string'.join は存在しなか
以下、リスト。
+if(defined? ' '.ord) # Ruby-1.9 def escape_meta_char( text ) text.gsub( META_CHAR_RE ) do |s| + '&#x%x;' % s[1].ord + end + end +else + def escape_meta_char( text ) + text.gsub( META_CHAR_RE ) do |s| '&#x%x;' % s[1] end end +end
いきなり Array#to_sと関係ないが String#[index] が Integerに代えて一文字の Stringを返すようにな
if digest - return View.new( diff, src.encoding, src.eol ).to_html_digest(overriding_tags, false).to_s.gsub( %r|<br />|, '' ).gsub( %r|\n</ins>|, "</ins>\n" ) + return View.new( diff, src.encoding, src.eol ).to_html_digest(overriding_tags, false).join(\).gsub( %r|<br />|, ).gsub( %r|\n</ins>|, "</ins>\n" ) else - return View.new( diff, src.encoding, src.eol ).to_html(overriding_tags, false).to_s.gsub( %r|<br />|, '' ).gsub( %r|\n</ins>|, "</ins>\n" ) + return View.new( diff, src.encoding, src.eol ).to_html(overriding_tags, false).join(\).gsub( %r|<br />|, ).gsub( %r|\n</ins>|, "</ins>\n" ) end
if digest - return View.new( diff, src.encoding, src.eol ).to_wdiff_digest({}, false).join.gsub( %r|\n\+\}|, "+}\n" ) + return View.new( diff, src.encoding, src.eol ).to_wdiff_digest({}, false).join(nil).gsub( %r|\n\+\}|, "+}\n" ) else - return View.new( diff, src.encoding, src.eol ).to_wdiff({}, false).join.gsub( %r|\n\+\}|, "+}\n" ) + return View.new( diff, src.encoding, src.eol ).to_wdiff({}, false).join(nil).gsub( %r|\n\+\}|, "+}\n" ) end
join('')か join(nil)か統一しろよ、とセルフツ
- before_change = Document.new(line[1].to_s, + before_change = Document.new(line[1].join(''), doc1.encoding, doc1.eol) - after_change = Document.new(line[2].to_s, + after_change = Document.new(line[2].join(''), doc2.encoding, doc2.eol)
if block_given? - source = yield block[1].to_s - target = yield block[2].to_s + source = yield block[1].to_a.join '' + target = yield block[2].to_a.join '' else - source = block[1].to_s - target = block[2].to_s + source = block[1].to_a.join '' + target = block[2].to_a.join '' end
block[i]は nilの可能性があるので to_a.join
if block_given? - source = yield entry[1].to_s - target = yield entry[2].to_s + source = yield entry[1].to_a.join '' + target = yield entry[2].to_a.join '' else - source = entry[1].to_s - target = entry[2].to_s + source = entry[1].to_a.join '' + target = entry[2].to_a.join '' end if i == 0 context_pre = "" # no pre context for the first entry else - context_pre = @difference[i-1][1].to_s.scan(context_pre_pat).to_s + context_pre = @difference[i-1][1].to_a.join('').scan(context_pre_pat).to_s end if (i + 1) == @difference.size context_post = "" # no post context for the last entry else - context_post = @difference[i+1][1].to_s.scan(context_post_pat).to_s + context_post = @difference[i+1][1].to_a.join('').scan(context_post_pat).to_s end
def source_lines() if @source_lines == nil - @source_lines = @difference.collect{|entry| entry[1]}.join.scan_lines(@eol) + @source_lines = @difference.collect{|entry| entry[1]}.join(nil).scan_lines(@eol)
def target_lines() if @target_lines == nil - @target_lines = @difference.collect{|entry| entry[2]}.join.scan_lines(@eol) + @target_lines = @difference.collect{|entry| entry[2]}.join(nil).scan_lines(@eol)
{{hoge a b 5}} #=> hoge('a', 'b', 5) {{hoge 'a' b(5)}} #=> hoge('a', 'b', 5) {{hoge ,a(, b)(5)}} #=> hoge('a', 'b', 5) {{hoge, a, b, 5}} #=> PluginException('not plugin method: hoge,') {{hoge; hage}} #=> PluginException
文法の緩さとか、一つのメソ
そり
require digest/md5
という風にライブラリ名をク
require :sqlite3
が通るのを一番に確認したけど、
defined? printf alias printg printf
を見て、
というのと同種の嫌悪を感じる。