What is the equivalent of Python's "%s" % "MyString"?

Hello!

I am studying Ruby and have been using Python.
I apologize for my negligence not to check out the whole document first.
What is the equivalent of the following Python’s expressions?

s = “My name is %s and my age is %d.” % (“Sam”, 34)

or

s = “My name is %(name)s and my age is %(age)d.” % {“name”: “Sam”, “age”:
34}

or

format = "My name is %(name)s and my age is %(age)d."
di = {“name”: “Sam”, “age”: 34}
s = format % di

I know that ruby has “#{name}” expression.
But that requires a variable named “name” in advance.
I want to bind the format string and data later.
What is the closest thing in ruby?
I find the python expression quite useful.

Thanks.

Sam

Hello!

I am studying Ruby and have been using Python.
I apologize for my negligence not to check out the whole document first.
What is the equivalent of the following Python’s expressions?

s = “My name is %s and my age is %d.” % (“Sam”, 34)

s = “My name is %s and my age is %d.” % [“Sam”, 34]

or

s = “My name is %(name)s and my age is %(age)d.” % {“name”: “Sam”, “age”:
34}

No direct equivalent in Ruby, but easy to implement:

def myformat(str, hash)
hash.each do |k,v|
str = str.gsub(“%(#{k})”, v)
end
str
end

s = myformat(“My name is %(name)s and my age is %(age)d.”, “name” => “Sam”, “age” => 34)

Of course you can redefine the % method in the same way.

Regards,

Michael

···

On Wed, Jun 02, 2004 at 03:43:42AM +0900, Sam Sungshik Kong wrote:

Sam Sungshik Kong wrote:

I know that ruby has “#{name}” expression.
But that requires a variable named “name” in advance.
I want to bind the format string and data later.
What is the closest thing in ruby?
I find the python expression quite useful.

Others have answered your original question, I think.

But I will point out (in case you do not know) that the
#{} notation is for arbitrary expressions, not just
variable names.

puts "The answer is #{2*pi*r}"

Hope this helps,
Hal

maybe even sprintf() can help you :slight_smile:

···

il Tue, 01 Jun 2004 18:38:32 GMT, “Sam Sungshik Kong” ssk@chol.nospam.net ha scritto::

I know that ruby has “#{name}” expression.
But that requires a variable named “name” in advance.
I want to bind the format string and data later.
What is the closest thing in ruby?
I find the python expression quite useful.

Hi,

Hello!

I am studying Ruby and have been using Python.

Good!

I apologize for my negligence not to check out the whole document first.
What is the equivalent of the following Python’s expressions?

s = “My name is %s and my age is %d.” % (“Sam”, 34)

This is almost identical in ruby:
“My name is %s and my age is %d.” % [“Sam”, 34]

or

s = “My name is %(name)s and my age is %(age)d.” % {“name”: “Sam”, “age”:
34}

or

format = “My name is %(name)s and my age is %(age)d.”
di = {“name”: “Sam”, “age”: 34}
s = format % di

I know that ruby has “#{name}” expression.
But that requires a variable named “name” in advance.
I want to bind the format string and data later.
What is the closest thing in ruby?
I find the python expression quite useful.

I don’t think Ruby supports this from itself.
Personally I find that #{} is enough in most cases.
If you really need this, you could define it with
the following code:

class String
alias :old_percent :%
def %(format)
return old_percent(format) if
not format.is_a? Hash

arr = []
str = self
while (match = /%\((.*?)\)/.match(str))
  str = match.post_match
  arr << format[match[1]]
end
self.gsub(/%\(.*?\)/, "%").old_percent(arr)

end
end

“My name is %(name)s and my age is %(age)d.” % {“name” => “Sam”, “age” =>
34}

Regards,
Kristof

···

On Tue, 01 Jun 2004 18:38:32 +0000, Sam Sungshik Kong wrote:

Hi,

At Wed, 2 Jun 2004 03:43:42 +0900,
Sam Sungshik Kong wrote in [ruby-talk:102028]:

s = “My name is %(name)s and my age is %(age)d.” % {“name”: “Sam”, “age”: 34}

I know that ruby has “#{name}” expression.
But that requires a variable named “name” in advance.
I want to bind the format string and data later.

I proposed that feature once in [ruby-dev:16351], though
rejected, but still I think that it would be useful for I18N.
Is it worth for RCR?

···


Nobu Nakada

You could still use the NUMBER$ syntax of printf. That is less convenient
as the fields are numbered rather than named:

print “%2$s is after %1$s\n” % [“one”, “two”]
==> two is after one

print “%1$s is before %2$s\n” % [“one”, “two”]
==> one is before two

ambrus

···

On Wed, Jun 02, 2004 at 03:43:42AM +0900, Sam Sungshik Kong wrote:

Hello!

s = “My name is %(name)s and my age is %(age)d.” % {“name”: “Sam”, “age”:
34}

That would be a nice feature. And it struck me that perhaps you could
use the keen suggestion by Michael Neumann mneumann@ntecs.de
to do something like that

def myformat(str, hash)
hash.each do |k,v|
str = str.gsub(“%(#{k})”, v)
end
str
end

···

nobu.nokada@softhome.net wrote:

Hi,

At Wed, 2 Jun 2004 03:43:42 +0900,
Sam Sungshik Kong wrote in [ruby-talk:102028]:

s = “My name is %(name)s and my age is %(age)d.” % {“name”: “Sam”, “age”: 34}

I know that ruby has “#{name}” expression.
But that requires a variable named “name” in advance.
I want to bind the format string and data later.

I proposed that feature once in [ruby-dev:16351], though
rejected, but still I think that it would be useful for I18N.
Is it worth for RCR?

s = ‘%string is number %digit’
#then define its vars
h = {'string=> ‘ruby’,‘digit’=>1}

#parse
p myformat(s,h)

string manipulation elegance is one of ruby’s strengths, i think

there are neat ways to use string#scan and blocks for this too.
Index

:paul

“Michael Neumann” mneumann@ntecs.de schrieb im Newsbeitrag
news:20040601185436.GA19522@miya.intranet.ntecs.de

Hello!

I am studying Ruby and have been using Python.
I apologize for my negligence not to check out the whole document first.
What is the equivalent of the following Python’s expressions?

s = “My name is %s and my age is %d.” % (“Sam”, 34)

s = “My name is %s and my age is %d.” % [“Sam”, 34]

or

s = “My name is %(name)s and my age is %(age)d.” % {“name”: “Sam”,
“age”:
34}

No direct equivalent in Ruby, but easy to implement:

def myformat(str, hash)
hash.each do |k,v|
str = str.gsub(“%(#{k})”, v)
end
str
end

s = myformat(“My name is %(name)s and my age is %(age)d.”, “name” =>
“Sam”, “age” => 34)

May I just add a simple performance optimization?

def myformat(str, hash)
str = str.dup
hash.each do |k,v|
str.gsub!(“%(#{k})”, v)
end
str
end

This saves you a lot intermediate strings that are thrown away immediately.

But I like this even more, since it needs less lines:

def myformat(str, hash)
str.gsub( %r{%((\w+))} ) {hash[$1]}
end

myformat(“My name is %(name)s and my age is %(age)d.”, “name” => “Sam”,
“age” => 34)
=> “My name is Sams and my age is 34d.”

Regards

robert
···

On Wed, Jun 02, 2004 at 03:43:42AM +0900, Sam Sungshik Kong wrote:

nobu.nokada@softhome.net wrote in message news:200406020151.i521pOHY005774@sharui.nakada.niregi.kanuma.tochigi.jp

Hi,

At Wed, 2 Jun 2004 03:43:42 +0900,
Sam Sungshik Kong wrote in [ruby-talk:102028]:

s = “My name is %(name)s and my age is %(age)d.” % {“name”: “Sam”, “age”: 34}

I know that ruby has “#{name}” expression.
But that requires a variable named “name” in advance.
I want to bind the format string and data later.

I proposed that feature once in [ruby-dev:16351], though
rejected, but still I think that it would be useful for I18N.
Is it worth for RCR?

Do you have an example on how would you use this? I ask because I
would also vote strongly against it.

One of the things that I really loved about ruby while learning it was
its “#{}” syntax, as it seemed to me a much more consistent way of
achieving what sprintf, $, %, etc. have been trying for years to
achieve in languages like C, perl, python, etc.

To achieve the above for quick testing, it is much easier and readable
to just do:
s = “My name is #{‘Sam’} and my age is #{34}.”

Then, later, if the need for a hash or an object really does arise,
you can easily do:
p = { :name => ‘Sam’, :age => 34 }
s = “My name is #{p[:name]} and my age is #{p[:age]}.”

If you have say a Person object with proper accessors, it is even
nicer to read:
p = Person.new(:name=>‘Sam’, :age => 34)
s = “My name is #{p.name} and my age is #{p.age}.”

Better yet, if you call a simple function within, it is still very
readable. Ex:
s = “My name is #{p.name.upcase} and my age is #{p.age}.”

The %s syntax is anything but readable once you have more than 3
elements. Using a hash to try to clarify it seems to me more of a
crutch for languages that do not support ruby’s extremely powerful
“#{}” formating.
That syntax still forces me to look for meaning of the text format
string in two different places (in the location of the text and at the
end of it), instead of in a single place as I read the string, which
seems like a step backwards overall.

nobu.nokada@softhome.net wrote in message
news:200406020151.i521pOHY005774@sharui.nakada.niregi.kanuma.tochigi.jp

Hi,

At Wed, 2 Jun 2004 03:43:42 +0900,
Sam Sungshik Kong wrote in [ruby-talk:102028]:

s = “My name is %(name)s and my age is %(age)d.” % {“name”: “Sam”,
“age”: 34}

I know that ruby has “#{name}” expression.
But that requires a variable named “name” in advance.
I want to bind the format string and data later.

I proposed that feature once in [ruby-dev:16351], though
rejected, but still I think that it would be useful for I18N.
Is it worth for RCR?

Do you have an example on how would you use this? I ask because I would
also vote strongly against it.

One of the things that I really loved about ruby while learning it was
its “#{}” syntax, as it seemed to me a much more consistent way of
achieving what sprintf, $, %, etc. have been trying for years to
achieve in languages like C, perl, python, etc.

Incorrect thinking, I’m afraid. printf and friends are better than #{}
for formatted printing; i.e. specifying field widths, precision, and so
on. In fact, #{} doesn’t even attempt to do formatting. So there’s room
in the world for both.

An example:

format = " %-25(name)s | %5(age)d | %10.2(salary)f \n"
records.each do |r|
printf format, :name => r.name, :age => r.age, :salary => r.salary
end

That’s superior to the existing printf capabilities because it’s clearer
and the order of the parameters are independent of the format.

Cheers,
Gavin

Hi,

···

On Wed, 02 Jun 2004 08:47:30 +0200, Robert Klemme wrote:

def myformat(str, hash)
str.gsub( %r{%((\w+))} ) {hash[$1]}
end

myformat(“My name is %(name)s and my age is %(age)d.”, “name” => “Sam”,
“age” => 34)
=> “My name is Sams and my age is 34d.”

I don’t think that’s the output he wanted. He wanted
to have de value of %(name)s converted to a string,
and %(age)d to a number (see my other post for an
implementation).

Kristof

GGarramuno@aol.com (GGarramuno) wrote in message news:af53b0ba.0406012346.42f73e84@posting.google.com

Sam Sungshik Kong wrote in [ruby-talk:102028]:

s = “My name is %(name)s and my age is %(age)d.” % {“name”: “Sam”, “age”:
34}

Do you have an example on how would you use this? I ask because I
would also vote strongly against it.

To achieve the above for quick testing, it is much easier and readable
to just do:
s = “My name is #{‘Sam’} and my age is #{34}.”

Not that I’d vote for the RCR, but here’s something that you can’t
(easily) do with the syntax you suggest:

FOO_en = "Some string about %{blah} that is reused in about "+
“%{value} different places in the program.”
FOO_de = "In %{value} Plaetze in Dieser Programme findet Das Satz
ueber “+
" %{blah}.”
LANGS = { :en => FOO_en, :de => FOO_de }

def print_foo( args )
puts LANGS[ @lang ] % {“blah” => “apples”, “value” => “a hundred”
}
end

(Sorry for butchering the German. It has been a long, long while since
I’ve used it.)

— SER

Thanks to all who replied to my question.

I want to mention one thing.
One drawback of ruby’s #{name} mechanism is that the variable ‘name’ must
exist before I setup the format and another drawback is that when I setup
the format the result string is already made (returned) and cannot be
delayed (if I’m correct…).
Sometimes I want to make the format first, especially when I write scripts
for web pages with python (now ruby :-)).

In python for ASP, for instance, I frequently write the following style
code.

html = “”"

%(name)s
%(age)d

“”"
di = {
“name”: get_name_from_db(),
“age”: get_age_from_db()
}
Response.Write(html % di)

Well, I may change the sequence (get the values first and setup the
formatting string).
However, in the above case, formatting is outer bound and the values are
details.
My brain feels more comfortable in this way…;^)

Sam

“GGarramuno” GGarramuno@aol.com wrote in message
news:af53b0ba.0406012346.42f73e84@posting.google.com

nobu.nokada@softhome.net wrote in message
news:200406020151.i521pOHY005774@sharui.nakada.niregi.kanuma.tochigi.jp

Hi,

At Wed, 2 Jun 2004 03:43:42 +0900,
Sam Sungshik Kong wrote in [ruby-talk:102028]:

s = “My name is %(name)s and my age is %(age)d.” % {“name”: “Sam”,
“age”: 34}

···

I know that ruby has “#{name}” expression.
But that requires a variable named “name” in advance.
I want to bind the format string and data later.

I proposed that feature once in [ruby-dev:16351], though
rejected, but still I think that it would be useful for I18N.
Is it worth for RCR?

Do you have an example on how would you use this? I ask because I
would also vote strongly against it.

One of the things that I really loved about ruby while learning it was
its “#{}” syntax, as it seemed to me a much more consistent way of
achieving what sprintf, $, %, etc. have been trying for years to
achieve in languages like C, perl, python, etc.

To achieve the above for quick testing, it is much easier and readable
to just do:
s = “My name is #{‘Sam’} and my age is #{34}.”

Then, later, if the need for a hash or an object really does arise,
you can easily do:
p = { :name => ‘Sam’, :age => 34 }
s = “My name is #{p[:name]} and my age is #{p[:age]}.”

If you have say a Person object with proper accessors, it is even
nicer to read:
p = Person.new(:name=>‘Sam’, :age => 34)
s = “My name is #{p.name} and my age is #{p.age}.”

Better yet, if you call a simple function within, it is still very
readable. Ex:
s = “My name is #{p.name.upcase} and my age is #{p.age}.”

The %s syntax is anything but readable once you have more than 3
elements. Using a hash to try to clarify it seems to me more of a
crutch for languages that do not support ruby’s extremely powerful
“#{}” formating.
That syntax still forces me to look for meaning of the text format
string in two different places (in the location of the text and at the
end of it), instead of in a single place as I read the string, which
seems like a step backwards overall.

“Kristof Bastiaensen” kristof@vleeuwen.org schrieb im Newsbeitrag
news:pan.2004.06.02.10.45.26.409952@vleeuwen.org

Hi,

def myformat(str, hash)
str.gsub( %r{%((\w+))} ) {hash[$1]}
end

myformat(“My name is %(name)s and my age is %(age)d.”, “name” =>
“Sam”,
“age” => 34)
=> “My name is Sams and my age is 34d.”

I don’t think that’s the output he wanted. He wanted
to have de value of %(name)s converted to a string,
and %(age)d to a number (see my other post for an
implementation).

Quite easy to fix:

def myformat(str, hash)
str.gsub( %r{%((\w+))(.)?} ) do
val = hash[$1]

case $2
  when 'd'
    val.to_i
  when nil, 's'
    val.to_s
  else
    val
end

end
end

myformat(“My name is %(name)s and my age is %(age)d.”, “name” => “Sam”,
“age” => 34)
=> “My name is Sam and my age is 34.”

Or even more OO and in fact using less LOC:

CONV = Hash.new( lambda {|x| x} ).update( {
‘d’ => lambda {|x| x.to_i }
} )

def myformat2(str, hash)
str.gsub( %r{%((\w+))([dsi])?} ) { CONV[$2].call hash[$1] }
end

myformat2(“My name is %(name)s and my age is %(age)d.”, “name” =>
“Sam”, “age” => 34)
=> “My name is Sam and my age is 34.”

Regards

robert
···

On Wed, 02 Jun 2004 08:47:30 +0200, Robert Klemme wrote:

Hi –

Thanks to all who replied to my question.

I want to mention one thing.
One drawback of ruby’s #{name} mechanism is that the variable ‘name’ must
exist before I setup the format and another drawback is that when I setup
the format the result string is already made (returned) and cannot be
delayed (if I’m correct…).

I wouldn’t describe it as a drawback, though; it’s just what that
mechanism (interpolation) is. It’s different from placeholding a
variable name.

In fact, #{var} is just one particular case of #{…}, where … can
be any expression. The whole thing is not designed around variables
and their names; it much more general. And in a case like:

puts “Two plus two is #{2+2}.”

you can’t have 2+2 not exist already :slight_smile:

David

···

On Thu, 3 Jun 2004, Sam Sungshik Kong wrote:


David A. Black
dblack@wobblini.net

"Sam Sungshik Kong" <ssk@chol.nospam.net> wrote in message news:<rMmvc.63963$Wf7.46733@newssvr29.news.prodigy.com>...

Thanks to all who replied to my question.

I want to mention one thing.
One drawback of ruby's #{name} mechanism is that the variable 'name' must
exist before I setup the format and another drawback is that when I setup
the format the result string is already made (returned) and cannot be
delayed (if I'm correct...).
Sometimes I want to make the format first, especially when I write scripts
for web pages with python (now ruby :-)).

In python for ASP, for instance, I frequently write the following style
code.

html = """
    <tr>
        <td>%(name)s</td>
        <td>%(age)d</td>
    </tr>
"""
di = {
    "name": get_name_from_db(),
    "age": get_age_from_db()
}
Response.Write(html % di)

Well, I may change the sequence (get the values first and setup the
formatting string).
However, in the above case, formatting is outer bound and the values are
details.
My brain feels more comfortable in this way...;^)

Sam

what about?...

require 'ostruct'
di = OpenStruct.new

html = """
  <tr>
     <td>%s</td>
     <td>%d</td>
  </tr>
"""

Response.Write(html % [di.name = "Sam", di.age = 34])

Or, something similar to that.

Hi,

I don’t think that’s the output he wanted. He wanted
to have de value of %(name)s converted to a string,
and %(age)d to a number (see my other post for an
implementation).

Quite easy to fix:

def myformat(str, hash)
str.gsub( %r{%((\w+))(.)?} ) do
val = hash[$1]

case $2
  when 'd'
    val.to_i
  when nil, 's'
    val.to_s
  else
    val
end

end
end

myformat(“My name is %(name)s and my age is %(age)d.”, “name” => “Sam”,
“age” => 34)
=> “My name is Sam and my age is 34.”

Or even more OO and in fact using less LOC:

CONV = Hash.new( lambda {|x| x} ).update( {
‘d’ => lambda {|x| x.to_i }
} )

def myformat2(str, hash)
str.gsub( %r{%((\w+))([dsi])?} ) { CONV[$2].call hash[$1] }
end

myformat2(“My name is %(name)s and my age is %(age)d.”, “name” =>
“Sam”, “age” => 34)
=> “My name is Sam and my age is 34.”

That’s nice, but unfortunately it doesn’t take into account
octal numbers and the other hairy sprintf details:

(I borrowed the gsub block thing…)

def myformat3(str, format)
arr =
str.gsub(/%((.*?))/) { arr << format[$1]; “%” } % arr
end

Regards,
Kristof

···

On Wed, 02 Jun 2004 14:26:18 +0200, Robert Klemme wrote:

"illocutionist" <gltewalt@yahoo.com> schrieb im Newsbeitrag
news:a081657b.0406051558.3b9c7349@posting.google.com...

"Sam Sungshik Kong" <ssk@chol.nospam.net> wrote in message

news:<rMmvc.63963$Wf7.46733@newssvr29.news.prodigy.com>...

> Thanks to all who replied to my question.
>
> I want to mention one thing.
> One drawback of ruby's #{name} mechanism is that the variable 'name'

must

> exist before I setup the format and another drawback is that when I

setup

> the format the result string is already made (returned) and cannot be
> delayed (if I'm correct...).
> Sometimes I want to make the format first, especially when I write

scripts

> for web pages with python (now ruby :-)).
>
> In python for ASP, for instance, I frequently write the following style
> code.
>
> html = """
> <tr>
> <td>%(name)s</td>
> <td>%(age)d</td>
> </tr>
> """
> di = {
> "name": get_name_from_db(),
> "age": get_age_from_db()
> }
> Response.Write(html % di)
>
> Well, I may change the sequence (get the values first and setup the
> formatting string).
> However, in the above case, formatting is outer bound and the values are
> details.
> My brain feels more comfortable in this way...;^)
>
> Sam
>
>
>

what about?...

require 'ostruct'
di = OpenStruct.new

html = """
  <tr>
     <td>%s</td>
     <td>%d</td>
  </tr>
"""

Response.Write(html % [di.name = "Sam", di.age = 34])

Or, something similar to that.

Disadvantage of this is that you need to know the order in which %
expressions appear in the string. Not very handy for larger web pages. The
lookup idiom (i.e. placing identifiers in the page that are looked up later)
can be handled far better especially during a longer lifetime of a project.

Regards

    robert

“Kristof Bastiaensen” kristof@vleeuwen.org schrieb im Newsbeitrag
news:pan.2004.06.02.17.33.01.599239@vleeuwen.org

Hi,

I don’t think that’s the output he wanted. He wanted
to have de value of %(name)s converted to a string,
and %(age)d to a number (see my other post for an
implementation).

Quite easy to fix:

def myformat(str, hash)
str.gsub( %r{%((\w+))(.)?} ) do
val = hash[$1]

case $2
  when 'd'
    val.to_i
  when nil, 's'
    val.to_s
  else
    val
end

end
end

myformat(“My name is %(name)s and my age is %(age)d.”, “name” =>
“Sam”,
“age” => 34)
=> “My name is Sam and my age is 34.”

Or even more OO and in fact using less LOC:

CONV = Hash.new( lambda {|x| x} ).update( {
‘d’ => lambda {|x| x.to_i }
} )

def myformat2(str, hash)
str.gsub( %r{%((\w+))([dsi])?} ) { CONV[$2].call hash[$1] }
end

myformat2(“My name is %(name)s and my age is %(age)d.”, “name” =>
“Sam”, “age” => 34)
=> “My name is Sam and my age is 34.”

That’s nice, but unfortunately it doesn’t take into account
octal numbers and the other hairy sprintf details:

Wasn’t meant to be a complete impl.

(I borrowed the gsub block thing…)

def myformat3(str, format)
arr =
str.gsub(/%((.*?))/) { arr << format[$1]; “%” } % arr
end

That looks nice! Now we just need inject() like behavior for gsub - then we
can save one more line. :slight_smile:

We can save one step of substitution anyway:

def myformat4(str, hash)
str.gsub( %r{%((\w+))([dsi])?} ) { “%#{$2}” % hash[$1] }
end

Note: I didn’t bother to look up all legal formatting characters.
Alternatively use [a-z] instead of [dsi]. And we can throw the last “?” out
if we require a formatting char like sprintf et al do.

This is not only cleaner but also more efficient I’d guess. (Didn’t
benchmark though.) In fact, it looks like the most natural implementation
to me.

Thanks for the nice sparring!

Kind regards

robert
···

On Wed, 02 Jun 2004 14:26:18 +0200, Robert Klemme wrote: