Here's my understanding:
* the 'ff' ligature is a non-word character (??)
Let’s go to the Unicode data: http://www.unicode.org/Public/9.0.0/ucd/UnicodeData-9.0.0d4.txt (1.6mb long text file)
FB00;LATIN SMALL LIGATURE FF;Ll;0;L;<compat> 0066 0066;;;;N;;;;;
The first few fields, in order:
1. `FB00` code point
2. `LATIN SMALL LIGATURE FF` name
3. `Ll` general category, in this case “Letter, lowercase” c.f. Unicode character property - Wikipedia
4. `0` is it combining (c.f. https://en.wikipedia.org/wiki/Combining_character\) 0 means it’s not
5. `L` what direction? `L` means left-to-right language
This meets some standard for being a word character, since the `Ll` category means it can be treated like a lowercase letter.
* it has a case conversion, so is affected by the //i flag
Unicode’s special casing data http://www.unicode.org/Public/9.0.0/ucd/SpecialCasing-9.0.0d6.txt specifies how to upper-, lower-, and title-case it:
FB00; FB00; 0046 0066; 0046 0046; # LATIN SMALL LIGATURE FF
1. `FB00` code point
2. `FB00` lower case (same)
3. `0046 0066` title case it as code points \x46 and \x66, i.e. `Ff`
4. `0046 0046` upper case it as code points \x46 and \x46, i.e. `FF`
Ruby doesn’t upper-case the ligature correctly:
"ff".upcase.codepoints.map{|x| x.to_s 16} #=> ["fb00"]
"ff".codepoints #=> [64256]
"ff".upcase.codepoints #=> [64256]
So:
* /ff/ is a subset of /\W/
Possibly incorrectly.
* /ff/i matches 'ff', 'FF', 'ff', 'fF', and 'Ff'
Makes perfect sense.
* therefore /\W/i should match all of the above
Nice proof!
I believe there is some complication about using a character class
(/[\W]/i, or even /[^\W]/i) which may or may not be implementation detail,
bug, or deeper complexity. I dunno.
All of the above, probably 
···
On 30 Jan 2016, at 17:13, Matthew Kerwin wrote: