2013-02-16 17 views
5

Ben bir sonraki öğenin bayt uzunluğunu ve sonra bu öğenin baytlarını ve sonra bir sonraki öğenin baytını, vb. Belirterek bir tamsayıya sahip olacak şekilde bir şekilde oluşturulmuş bir dizi 3 dizgim var. Eğer biri yaptıysa:Ruby String # paketini açmak

[a.bytesize, a, b.bytesize, b, c.bytesize, c].pack("na*na*na*") 

Bunu basit bir şekilde nasıl açabilirim? Bu sorunun Perl çözümdü: Daha kolay bir

vals = [] 
3.times do 
    size = data.unpack("n").first 
    data.slice!(0, 2) 
    vals << data.unpack("a#{size}").first 
    data.slice!(0, size) 
end 

var mı: görünüşte açmak içinde '/' ve parantez desteklemez yakut için

my($a, $b, $c) = unpack("(n/a*)3", $data) 

, şöyle bir şey kullanıyorum Bunun yolu?

+1

, ben Ruby'nin sorun izleyicide üzerinde unpack genişletmek için bir özellik talep etmeyi uygulama bazı Perl özelliklerini alırsa, işe yarayabileceğini gibi görünüyor edeceğiz – Speed

cevap

0

Bunu Perl çözümü kadar kolay bir şekilde göremiyorum (ve Ruby'nin paket/paket uygulamasına eklenen bir özellik için bir özellik isteğini dosyalamak için iyi olacağını kabul ediyorum), ama en azından sağlayabilirim Daha az hatlarında çözüm eğer yardımcı olur: dövme un çalışan döngüler açar yerine, http://bindata.rubyforge.org/ bunu kullanmak gerektiğini düşünüyorum:

vals = [] 
until data.empty? 
    vals << data.slice!(0, data.slice!(0,2).unpack('n').first.to_i).unpack("a*").first 
end 
0

Eğer herhangi bir ciddi ikili veri işleme gerekiyorsa, bunun için bir mücevher var.

Tabii bir özellik isteğinde bulunabilirsiniz ve uygulanmasını bekleyiniz, Ancak bunun yerine bindata gem'i kullanmanızı öneririz, ki bu çok daha güçlü bir çözüm IMO'dur.

1

IMHO, PERL kadar kolay değildir, ancak önerebileceğim bir çözüm budur. birisi mi basit bir çözüm bulmazsa

unpacked = [] 
a, b, c = *unpacked << data.slice!(0, data.slice!(0, 2).unpack('S>').first) \ 
      until data.empty?