StructとYAMLの仲を取り持つHash
StructとYAMLとHashが連携する機会が多いので最も頑張っているHashにヘルパーさんをつけることにした
HashHelperとその働き
# coding: CP932 require "yaml" require "pp" module HashHelper module ClassMethods def new_each_block new { |hash, key| hash[key] = self.new_each_block } end end module InstanceMethods def to_struct Struct.new( *self.keys ) .new( *self.values.map{ |e| Hash === e ? e.to_struct : e } ) end end def self.included(receiver) receiver.extend ClassMethods receiver.send :include, InstanceMethods end end class Hash include HashHelper end module YOML class << self def dump( obj, io=nil ) sio = StringIO.new ( io || sio ) << YAML.dump_stream(obj).gsub(/":?.+"/) { |s| eval(s) } io ? io.close : sio.rewind && sio.read end end end if __FILE__ == $0 @dic = Hash.new_each_block @dic[:EJ][:I][:am][:a][:satisfied][:customer] = "そちらでの買い物に大変満足しています" @dic[:EJ][:I][:am][:a][:Christian] = "私はクリスチャンです" @dic[:EJ][:I][:am][:a][:dancer] = "【映画】華麗なるダンサー◆英1972" @dic[:EJ][:I][:got][:burned][:Christian] = "火傷をした" @dic[:EJ][:I][:got][:carried][:away] = %w{調子に乗り過ぎた はしゃぎ過ぎた 悪乗りし過ぎた} # 日本語メソッドは作れるが呼び出すのは困難 @dic[:JE][:私は][:クリスチャン][:です] = "I am a Christian" pp @dic YOML.dump( @dic, File.open( "dic.yaml", "w" ) ) dic = YAML.load( File.open( "dic.yaml" ) ).to_struct puts dic.EJ.I.am.a.satisfied.customer puts dic.EJ.I.am.a.dancer puts dic.EJ.I.got.carried.away*"/" end
出力結果(ハッシュ)
{:EJ=> {:I=> {:am=> {:a=> {:satisfied=>{:customer=>"そちらでの買い物に大変満足しています"}, :Christian=>"私はクリスチャンです", :dancer=>"【映画】華麗なるダンサー◆英1972"}}, :got=> {:burned=>{:Christian=>"火傷をした"}, :carried=>{:away=>["調子に乗り過ぎた", "はしゃぎ過ぎた", "悪乗りし過ぎた"]}}}}, :JE=>{:私は=>{:クリスチャン=>{:です=>"I am a Christian"}}}}
出力結果(ハッシュの値)
そちらでの買い物に大変満足しています 【映画】華麗なるダンサー◆英1972 調子に乗り過ぎた/はしゃぎ過ぎた/悪乗りし過ぎた
YAML.dumpの全角文字バイナリ文字列化ちょい対策
YAMLのエンジンにPsychを利用するという本来の対策ができなかった(libyamlの入れ方がわからない)
Windowsでのlibyaml入れ方教えてー!エライ人!!
と困ったままというわけにはいかないので取りあえずeval使って全角文字に戻した
YOML
# coding: CP932 require "yaml" module YOML class << self def dump( obj, io=nil ) sio = StringIO.new ( io || sio ) << YAML.dump_stream(obj).gsub(/":?.+"/) { |s| eval(s) } io ? io.close : sio.rewind && sio.read end end end if __FILE__ == $0 months = { OLD: { 睦月: 1, 如月: 2, 弥生: 3, 卯月: 4, 皐月: 5, 水無月: 6, 文月: 7, 葉月: 8, 長月: 9, 神無月: 10, 霜月: 11, 師走: 12, }, :KANJI => { "一月" => 1, "二月" => 2, "三月" => 3, "四月" => 4, "五月" => 5, "六月" => 6, "七月" => 7, "八月" => 8, "九月" => 9, "十月" => 10, "十一月" => 11, "十二月" => 12, }, } puts YAML.dump( months ) puts YOML.dump( months ) YAML.dump( months, File.open( "months.yaml", "w" ) ) YOML.dump( months, File.open( "months.yoml", "w" ) ) end
evalを使わなくて良い方法も教えてー!エライ人!!
YAML.dump出力
--- :OLD: ":\x96r\x8C\x8E": 1 ":\x94@\x8C\x8E": 2 ":\x96\xED\x90\xB6": 3 ":\x89K\x8C\x8E": 4 ":\x8EH\x8C\x8E": 5 ":\x90\x85\x96\xB3\x8C\x8E": 6 ":\x95\xB6\x8C\x8E": 7 ":\x97t\x8C\x8E": 8 ":\x92\xB7\x8C\x8E": 9 ":\x90_\x96\xB3\x8C\x8E": 10 ":\x91\x9A\x8C\x8E": 11 ":\x8Et\x91\x96": 12 :KANJI: "\x88\xEA\x8C\x8E": 1 "\x93\xF1\x8C\x8E": 2 "\x8EO\x8C\x8E": 3 "\x8El\x8C\x8E": 4 "\x8C\xDC\x8C\x8E": 5 "\x98Z\x8C\x8E": 6 "\x8E\xB5\x8C\x8E": 7 "\x94\xAA\x8C\x8E": 8 "\x8B\xE3\x8C\x8E": 9 "\x8F\\\x8C\x8E": 10 "\x8F\\\x88\xEA\x8C\x8E": 11 "\x8F\\\x93\xF1\x8C\x8E": 12
YOML.dump出力
--- :OLD: :睦月: 1 :如月: 2 :弥生: 3 :卯月: 4 :皐月: 5 :水無月: 6 :文月: 7 :葉月: 8 :長月: 9 :神無月: 10 :霜月: 11 :師走: 12 :KANJI: 一月: 1 二月: 2 三月: 3 四月: 4 五月: 5 六月: 6 七月: 7 八月: 8 九月: 9 十月: 10 十一月: 11 十二月: 12
Ruby1.9でexe化 - ocra
exe化
引数あり
ocra hoge.rb -- ora
メモ:修正した行は?修正してない行は?
ちょっとした確認依頼にちょっとしたコードで対応できるRubyって素敵
依頼内容を聞きつつコードを書くのが当たり前になりつつある(^^ゞ
# files before = File.open("before.csv").lines.to_a after = File.open("after.csv").lines.to_a # conditions matched = lambda{|(b, a)| b==a} mismatched = lambda{|(b, a)| b!=a} # select+map matched_before = before.zip(after).grep(matched){|(b, a)| b} matched_after = before.zip(after).grep(matched){|(b, a)| a} mismatched_before = before.zip(after).grep(mismatched){|(b, a)| b} mismatched_after = before.zip(after).grep(mismatched){|(b, a)| a} # display { "matched:before" => matched_before, "matched:after" => matched_after, "mismatched:before" => mismatched_before, "mismatched:after" => mismatched_after, }.each{|header, data| puts [header, data]}
業務運用担当者なので電話での問い合わせ対応を結構するのだが、話しながら
irbを立ち上げて対応していることが多い(^^)
ファイルやディレクトリの検索、ファイル内検索、話相手に確認を取りながら
柔軟に調べる必要がある場合などで本当に役に立っている
Windowsも標準装備にしてくれないかなー
メモ:遺物
# coding: CP932 require "tapp" require "inifile" # gem install inifile #require "yaml" require "json" require "xmlsimple" # gem install xml-simple def to_json(hash) hash.to_json.encode(__ENCODING__) end def to_xml(hash) XmlSimple.xml_out(hash) end Dir["./**/*.ini"].each do |path| basename = File.basename(path, ".*") IniFile.new(path).tapp.to_h.tap do |hash| %w{json xml}.each do |to| File.open("#{basename}.#{to}", "w") do |fp| fp << send("to_#{to}", hash) end end end end
メモ:ダメだ(>_<)
# coding: CP932 # 生成パターン PATTERN = { SEQ: -> size, n {1.upto(1.0/0).take(n).map{|i| "%0#{size}d"%i}}.curry, HIRA: -> size, n {('ぁ'..'ん').cycle.take(size * n).each_cons(size).map(&:join)}.curry, KATA: -> size, n {(('ァ'..'ン').to_a+('ヴ'..'ヶ').to_a).cycle.take(size * n).each_cons(size).map(&:join)}.curry, KANJI: -> size, n {('亜'..'熙').cycle.take(size * n).each_cons(size).map(&:join)}.curry, } # 区切り文字 DELIMITTER = "\t" # 列定義 cols = [ PATTERN[:SEQ][6], PATTERN[:HIRA][3], PATTERN[:KATA][4], PATTERN[:KANJI][5], ] # 行定義 rows = Array.new(25) # データ生成 rows.tap{|rows| puts rows.zip( *cols.map{ |col| col[rows.size] } ) .map { |data| data.drop(1).join("\t") } }
出力
000001 ぁあぃ ァアィイ 亜唖娃阿哀 000002 あぃい アィイゥ 唖娃阿哀愛 000003 ぃいぅ ィイゥウ 娃阿哀愛挨 000004 いぅう イゥウェ 阿哀愛挨姶 000005 ぅうぇ ゥウェエ 哀愛挨姶逢 000006 うぇえ ウェエォ 愛挨姶逢葵 000007 ぇえぉ ェエォオ 挨姶逢葵茜 000008 えぉお エォオカ 姶逢葵茜穐 000009 ぉおか ォオカガ 逢葵茜穐悪 000010 おかが オカガキ 葵茜穐悪握 000011 かがき カガキギ 茜穐悪握渥 000012 がきぎ ガキギク 穐悪握渥旭 000013 きぎく キギクグ 悪握渥旭葦 000014 ぎくぐ ギクグケ 握渥旭葦芦 000015 くぐけ クグケゲ 渥旭葦芦鯵 000016 ぐけげ グケゲコ 旭葦芦鯵梓 000017 けげこ ケゲコゴ 葦芦鯵梓圧 000018 げこご ゲコゴサ 芦鯵梓圧斡 000019 こごさ コゴサザ 鯵梓圧斡扱 000020 ごさざ ゴサザシ 梓圧斡扱宛 000021 さざし サザシジ 圧斡扱宛姐 000022 ざしじ ザシジス 斡扱宛姐虻 000023 しじす シジスズ 扱宛姐虻飴 000024 じすず ジスズセ 宛姐虻飴絢 000025 すずせ スズセゼ 姐虻飴絢綾
メモ:固定長開始位置
DATAファイルオブジェクト
ps_data.rb
DATA.lines.map(&:chomp).tap{|sizes| puts sizes.inject([1]){|poses, size| poses << poses.last + size.to_i}.zip(sizes) .map{|(pos, size)| "#{pos}\t#{size}"} } __END__ 21 1 6 1 4 1 16 1 20 1 2 1 69 1 26 1 16 1 16 1 16 1 8 1 26 1 16 1 2
標準入力
サイズ入力(終了はCtrl+Z)→サイズファイル作成
copy con sizes.dat
ps_argf.rb
ARGF.lines.map(&:chomp).tap{|sizes| puts sizes.inject([1]){|poses, size| poses << poses.last + size.to_i}.zip(sizes) .map{|(pos, size)| "#{pos}\t#{size}"} }
実行
type sizes.dat | ruby ps_argf.rb
結果(DATA版、ARGF版)
1 21 22 1 23 6 29 1 30 4 34 1 35 16 51 1 52 20 72 1 73 2 75 1 76 69 145 1 146 26 172 1 173 16 189 1 190 16 206 1 207 16 223 1 224 8 232 1 233 26 259 1 260 16 276 1 277 2 279