Project

fstrings

0.0
No release in over 3 years
Low commit activity in last 3 years
Python-alike formatting strings with Ruby flavour: f"{x=%.2f}"
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

Runtime

 Project Readme

FStrings

FStrings is an experimental gem implementing Python-alike fstrings (formatting strings) in Ruby.

The idea is, in Ruby, we have two ways to insert some variable values in strings:

  1. String interpolation: puts "Foo #{value} bar"
  2. String#% (or Kernel#format, if you want): puts "Foo %.2f value" % value

First is more convenient (with the variable name where it should be rendered), while the second is much more powerful, allowing to specify various formatting flags. FStrings tries to close this gap, with a bit of idea stealing (from the Python) and a bit of dark magic (binding_of_caller).

Showcase

In its basic form, FStrings formatting looks just like string interpolation (just using {} instead of #{}):

require 'fstrings'
include FStrings

value = 5
puts f"Simple: {value}"
# => "Simple: 5"

But it also allows to specify formatting flags, after % sign (the regular Kernel#format's syntax works):

puts f"Formatted: {value%+i}"
# => "Formatted: +5"

float = 1.2345
puts f"Formatted: {float%.2f}"
# => "Formatted: 1.23"

That's mostly it! But not all of it :)

FStrings also support x= syntax (borrowed from the recent Python 3.8), indispensable for puts-debugging:

puts f"Named: {value=%+i}"
# => "Named: value=+5"

# Any expression can be interpolated this way:
r = 12
puts f"Circle area: {Math::PI * r**2 = %.3f}"
# => "Circle area: Math::PI * r**2 = 452.389"

FStrings allows to define custom formatters for your own classes, and automatically define one for Time (it passes the format string to strftime):

puts f"Current time is {Time.now %H:%M (%b %d)}"
# => "Current time is 15:00 (Jan 07)"

To define your own, just do this:

Point = Struct.new(:x, :y)
# First argument is formatted value, second is format string
FStrings.def_formatter(Point) { |val, str| str.gsub('%x', val.x.to_s).gsub('%y', val.y.to_s) }

point = Point.new(10, 20)

puts f"See, it works: {point %x;%y}"
# => "See, it works: 10;20"

(The formatting strings considered everything starting from the first % including it.)

Quirks and problems

The library is new and experimental. It is probably helpful in debugging, but probably not advised for any production. The problems I can think of:

  • binding_of_caller and eval are used inside. It is black and unholy magic, obviously;
  • funny f"foo" syntax is used to make it look like Python's native fstrings, which could be repulsive for some. In fact, it is just f() method, you can use it without include FStrings, with just FStrings.f();
  • fstrings-parser is not that mature; it is tested, but can break on more complicated strings (which you hopefully won't need for debugging);
  • probably, parsed strings should be cached, currently, they are not (so in a method which you call 2 mln times, could provide serious slowdown);
  • considering simplistic formatting string definition, statements using % can't be inspected (everything after % would be thought to be a formatting string).

Author & license