Class: PyFormat

Inherits:
Object show all
Defined in:
lib/tagen/core/string/pyformat.rb

Overview

Overview

a python like string format libraray.

  1. “this is #guten” # Ruby Builtin

  2. “this is %s” % “guten” # Ruby Builtin

  3. “this is %guten”.format(guten: ‘x’)

use “#var” is easy and quick in many cases, but some times we need a more powerful format support.

"I like %s and %s" % %(apple, football)
"I like %{fruit} and %{sport}".format('apple', 'football')   # it has semantic meaning.

Usage

require "tagen/core"
"it costs %{:.2f} dollars".format(1.123) #=> "it costs 1.12 dollars"
  • support abritry-argument or hash-argument “%{} %{}”.format(1,2) #=> “1 2” “%a %b”.format(a:1, b:2) #=> “1 2” “%a %b”.format(1, b:2) #=> “1 2”

  • escape “my \%name is %name”.format(“guten”) #=> my name is guten.

Examples

"%{:.2f}" 
"%{name:.2f}"

“I’m %guten and is #age years old”.format(guten: “guten”) # combine Ruby Buintin with PyFormat

Specification

format_spec ::=  [[fill]align][sign][#][0][width][,][.precision][type]
fill        ::=  <a character other than '}'> default is " " 
align       ::=  "<" | ">" | "=" | "^"   default is >.  = is padding after sign. eg. +000000120
sign        ::=  "+" | "-" | " "
#           ::=  <prefix 0b 0o 0x>
0           ::=  <zero_padding>  equal to fill is 0
,           ::=  <comma_sep> also type n
precision   ::=  string truncate with 
type        ::=  s c b o d x X f/F g/G e/E n % 

f/F   fixed point. nan/NAN inf/INF
e/E   exponent notation. 
g/G   gernal format.  1.0 => 1
n     number. thounds sep based on local setting

Resources

Defined Under Namespace

Classes: Field

Constant Summary collapse

Error =
Class.new Exception
EFormatSpec =
Class.new Error
EFieldName =
Class.new Error

Instance Method Summary collapse

Constructor Details

#initialize(fmt) ⇒ PyFormat

Returns a new instance of PyFormat.

Parameters:



65
66
67
# File 'lib/tagen/core/string/pyformat.rb', line 65

def initialize fmt
	@fmt = fmt
end

Instance Method Details

#format(*args) ⇒ String

format a string

Parameters:

Returns:



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/tagen/core/string/pyformat.rb', line 73

def format *args
	# if 'field' in argh
	#   return argh[field]
	# else
	#   return args.shift
	# end

	# args -> argh and args
	argh = Hash===args[-1] ? args.pop : {}

	# "%{0:.5f}"
	pat = /
		\\%{.*?}  # esacpe
	  | %{ (.*?)? (?: :(.*?) )? }  # %{0:.f}
		/x

	ret = @fmt.gsub(pat) do |m|
		if m.start_with? "\\%{"
			m
		else
			field, spec = $1, $2
			field = field.to_sym

			if argh.has_key? field
				arg = argh[field]
			else
				arg = args.shift

				# can't use if arg==nil then .. 
				#
				# class Guten
				#   def <=> other
				#     "{}".format(self)
				#   end
				# 
				# => SystemStackError
				#
				if NilClass === arg then raise EFieldName, "not enought arguments --#{args}" end
			end

			Field.parse spec, arg
		end
	end
	ret
end