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

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

Instance Method Summary (collapse)

Constructor Details

- (PyFormat) initialize(fmt)



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

def initialize fmt
	@fmt = fmt
end

Instance Method Details

- (String) format(*args)

format a string



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