[#49148] Ruby 1.9で、バイト長の部分文字列を作りたくて悩んでます — Daisuke Yokotsuka <yokots_d@...3-net.ne.jp>

はじめまして。横塚と申します。

16 messages 2013/01/29

[ruby-list:49160] Re: Ruby 1.9で、バイト長の部分文字列を作りたくて悩んでます

From: Takeshi Iogawa <alpha@246.ne.jp>
Date: 2013-01-29 14:29:41 UTC
List: ruby-list #49160
いおがわです。

> で、encodingの問題も、実行性能も、無事に解決できました。

お役に立てたようでよかったです。


> 他人が見て、何をやっているのか一目で理解できるコードかと言うと、ちょっ
と悩ましい。

Ruby は既存のクラスの挙動を変更できますから(組み込みのコアクラスでも!!)
以下のようなコードをスクリプトの最初のほうに記述しておく(もしくは別ファ
イルにしてrequire)って方法もあるにはあります。。。

# Stringクラスを拡張し、bytesliceメソッドを定義する
unless String.instance_methods.find {|m| m == :byteslice}
  class String
    def byteslice *a, &b
     enc = self.encoding
     r = self.force_encoding("BINARY").slice(*a, &b).force_encoding(enc)
     self.force_encoding enc
     r
    end
  end
end
# -- ここまで


そーすると、1.9.2 でも(1.9.1でも)
target = data.byteslice 0, 72

って書けますよ。(やってることは前回と変わらないですがforce_encoding が隠
蔽されるので見通しはよくなるかと。。。実行性能的には若干不利かな)
# 将来的に1.9.3以上にバージョン上げたときは標準のbytesliceが使われるよう
# になります。

(注) 1.9.3 のbyteslice の引数・戻り値をちゃんと調べ切れていないで上記
コード書いてますので、1.9.3に上げた途端にピギャー、となる可能性があります。
Try するなら1.9.3のbyteslice の仕様をきちんと確認ください

いわゆる『モンキーパッチ』という奴なのでむやみやたらと手を出さないほうが
よいと思います。
あくまで、「こんな手もある」というコトで。。。


(2013/01/29 21:20), Daisuke Yokotsuka wrote:
> いおがわ様
> 
> ご教示、ありがとうございます。
> 
> target = data.force_encoding("BINARY").slice(0,72).force_encoding("Windows-31J") ;
> 
> で、encodingの問題も、実行性能も、無事に解決できました。
> 
>> # ただ、force_encoding に頼るのはあまりよい方法ではない、と
>> # 考えますが。。。
> 
> ですよね。
> 他人が見て、何をやっているのか一目で理解できるコードかと言うと、ちょっと悩ましい。
> でも、とってもシンプルなコードになりました。
> ありがとうございます。
> あとはコメントで凌ぐということで・・・・
> 
>> ところで、余計なお世話ですが、1バイト文字とマルチバイト文字の
>> 混在する文字列を問答無用でぶった切るとあまりよくないことが
>> 起こったりしませんか? 特にSJISで"\" なんかが絡んでくると
>> いやらしいバグが出そうで気になります
> 
> はい、おっしゃる通りで、普通はこんなことはしないのですが、
> 今回は、固定書式のCOBOLソースの解析なので、コメント行以外に
> 72バイト目を跨る2バイトコードは存在しないという前提です。
> 
> ありがとうございました。
> 
> 横塚
> 
> 
> <5107AF72.9030507@246.ne.jp>  の、
>     "[ruby-list:49156] Re: Ruby 1.9で、バイト長の部分文字列を作りたくて悩んでます" において、
>     "Takeshi Iogawa<alpha@246.ne.jp>"さんは書きました:
> 
>> いおがわと申します。
>> MLの参加自体新参者なので僭越ですが。。。
>>
>> str = "7bit asciiが混じった長い文字列"
>> enc = str.encoding
>> str.force_encoding("BINARY").slice(0,72).force_encoding(enc)
>>
>> ではいかがでしょう?
>> # ただ、force_encoding に頼るのはあまりよい方法ではない、と
>> # 考えますが。。。
>>
>> ところで、余計なお世話ですが、1バイト文字とマルチバイト文字の
>> 混在する文字列を問答無用でぶった切るとあまりよくないことが
>> 起こったりしませんか? 特にSJISで"\" なんかが絡んでくると
>> いやらしいバグが出そうで気になります
>>
> 
> --
> Daisuke Yokotsuka
> 
> 

--
 Takeshi Iogawa


In This Thread