Have you ever combined heredocs with format strings:

<<TEMPLATE % [23, 42]
First value: %s
Second value: %s
TEMPLATE

Unusual to have the substitutions in the beginning, but I kind of like it 🤔

Format string docs: https://idiosyncratic-ruby.com/49-what-the-format.html

#ruby #rubystrings

Idiosyncratic Ruby: What the Format?

Documenting All Ruby Specialities.

We are kind of used to this, but still it is somhow illogical: A Range object, which represents *empty*, can still have an effect when used as a string index:

range = 0..-3
range.to_a.empty? #=> true
"Ruby"[range] #=> "Ru"

It feels less "wrong" when using Ruby's more recent beginless ranges:

"Ruby"[..-3] #=> "Ru"

#idiosyncratic #ruby #rubystrings

In #Ruby, you cannot create invalid UTF-8 string literals like "\u{D800}\u{D801}" (🚫 UTF-16 surrogates)

A helpful tool to still be able to create such strings is Array#pack:

str = [0xD800, 0xD801].pack("U*") # => "\xED\xA0\x80\xED\xA0\x81"
str.encoding # => #<Encoding:UTF-8>
str.valid_encoding? # => false

#rubystrings #unicode

More about Array#pack: https://idiosyncratic-ruby.com/4-what-the-pack.html

Idiosyncratic Ruby: What the Pack?

Documenting All Ruby Specialities.

#Ruby's String#sum method takes a bit count, which is handy for calculating the digit sum of a string of numbers:

"20221220".sum(4) #=>11

So how did this work? ASCII digits are represented by bytes from the 48..57 range, in binay that is

0b110000..0b111001

By passing 4 to sum, we define that only the four lower bits of each byte get used, like a bitwise or with a bitmask:

57&0b1111 #=>9

Voilà! We could express the above like this:

"20221220".bytes.map{ _1&0b1111}.sum #=>11

#rubystrings

Ruby strings have a sum method which will return the sum of all bytes used in the string:

"ab".sum # => 195

You can think of it as .bytes.sum:

"ab".bytes # [97, 98]
"ab".bytes.sum # => 195

However, this is not particularly useful when used with multi-byte encodings like UTF-8:

"⌨".sum #=> 534
"⌨".bytes # => [226, 140, 168]

"☜".sum #=> 534
"☜".bytes => [226, 152, 156]

Docs: https://ruby-doc.org/core/String.html#method-i-sum

#ruby #rubystrings

class String - RDoc Documentation

Let's start off by reviewing how strange Ruby's calculation of string successors can be:

"9z".succ #=> "10a"
"z9".succ #=> "aa0"

Docs: https://ruby-doc.org/core/String.html#method-i-succ

#ruby #rubystrings

class String - RDoc Documentation

I once created an account on the birdsite that would just post some lesser known tidbits about using strings in #Ruby. Will repost some of them here over the next days (+ new stuff I come across) #rubystrings