Jerome
Jerome

Reputation: 6221

Ruby pack and Latin (high-ASCII) characters

An action outputs a fixed-length string via Ruby's pack function

clean = [edc_unico,  sequenza_sede, cliente_id.to_s, nome, indirizzo, cap,  comune, provincia, persona, note, telefono,  email]
string  = clean.pack('A15A5A6A40A35A5A30A2A40A40A18A25')

However, the data is in UTF-8 as to allow latin/high-ascii characters. The result of the pack action is logical. high-ascii characters take the space of 2 regular ascii characters. The resulting string is shortened by 1 space character, defeating the original purpose.

What would be a concise ruby command to interpret high-ascii characters and thus add an extra space at the end of each variable for each high-ascii character, so that the length can be brought to its proper target? (note: I am assuming there is no directive that addresses this specifically, and the whole lot of pack directives is mind-muddling)

update an example where the second line shifts positions based on accented characters

CNFrigo                                         539                                     Via Privata Da Via Iseo 6C                                            20098San Giuliano Milanese         MI02 98282410                         02 98287686       12886480156     12886480156 Bo3                 Euro                Giuseppe Frigo Transport 349 2803433                                                                                                                                                                                                                                                                   [email protected] [email protected]      
CNIn's M                                        497                                     Via Istituto S.Maria della Pietà,                                    30173Venezia                       Ve041 8690111       340 6311408       0041 5136113      00115180283     02896940273 B60Fm               Euro                Per Documentazioni Tecniche Inviare Materiale A : [email protected] Amministrazione : [email protected] Silvia Scarpa Per Liberatorie 041/5136171 Sig.Ra Bianco Per Pagamento Fatture 041/5136111 (Solo Il Giovedi Pomeriggio Dalle 14 All                                        [email protected]           

Upvotes: 0

Views: 111

Answers (1)

matt
matt

Reputation: 79743

It looks like you are trying to use pack to format strings to fixed width columns for display. That’s not what it’s for, it is generally used for packing data into fixed byte structures for things like network protocols.

You probably want to use a format string instead, which is better suited for manipulating data for display.

Have a look at String#% (i.e. the % method on string). Like pack it uses another little language which is defined in Kernel#sprintf.

Taking a simplified example, with the two arrays:

plain = ["Iseo", "Next field"]
accent = ["Pietà", "Next field"]

then using pack like this:

puts plain.pack("A10A10")
puts accent.pack("A10A10")

will produce a result that looks like this, where “Next field” isn’t aligned since pack is dealing with the width in bytes, not the displayed width:

Iseo      Next field
Pietà    Next field

Using a format string, like this:

puts "%-10s%-10s" % plain
puts "%-10s%-10s" % accent

produces the desired result, since it is dealing with the displayable width:

Iseo      Next field
Pietà     Next field

Upvotes: 1

Related Questions