String#decorate

When chaining methods, it’d be neat to have something that was passed
in the string and returned a ‘decorated’ version, e.g.

pp = ary.join(",").decorate {|s| “[#{s}]”}
attrib = title.capitalize.decorate {|t| “\t – #{author[t]},”#{t}""}
(n*100).to_s.decorate {|p| “#{p}% done”}

as opposed to equivalents using String#+ and String#=, or even the
fully functional but just a trifle ugly String.gsub /.*/ {|s| …}

Not quite an RCR (it’s trivially implementable anyway) - just wanted
to see what people thought of the idea, and in particular if anyone
had nicer names to suggest.

martin

pp = ary.join(",").decorate {|s| "[#{s}]"}
attrib = title.capitalize.decorate {|t| "\t -- #{author[t]},\"#{t}\""}
(n*100).to_s.decorate {|p| "#{p}% done"}

Something like this ?

svg% ri String#%
--------------------------------------------------------------- String#%
     str % arg -> aString

···

------------------------------------------------------------------------
     Format---Uses str as a format specification, and returns the result
     of applying it to arg. If the format specification contains more
     than one substitution, then arg must be an Array containing the
     values to be substituted. See Kernel::sprintf on page 427 for
     details of the format string.
        "%05d" % 123 #=> "00123"
        "%-5s: %08x" % [ "ID", self.id ] #=> "ID : 200e0648"

svg%

Guy Decoux

When chaining methods, it’d be neat to have something that was passed
in the string and returned a ‘decorated’ version, e.g.

pp = ary.join(“,”).decorate {|s| “[#{s}]”}

I assume you want ‘pp’ to contain: “(1),(2),(3)” ?
If so then I don’t think your example will work:
1st you join the array into a string
2nd you decorate each array-element (impossible).

Instead prefer supplying a block to #join which does the decoration.
[1, 2, 3].join(", ") {|s| “(#{s})”}

“(1), (2), (3)”

attrib = title.capitalize.decorate {|t| “\t – #{author[t]},"#{t}"”}
(n*100).to_s.decorate {|p| “#{p}% done”}

These cases could be useful.

Not quite an RCR (it’s trivially implementable anyway) - just wanted
to see what people thought of the idea, and in particular if anyone
had nicer names to suggest.

It works a bit like ‘collect’ or ‘map’

how about

title.capitalize.map {|t| “\t – #{author[t]},"#{t}"”}

···

On Sun, 22 Jun 2003 06:46:00 +0000, Martin DeMello wrote:


Simon Strandgaard

When chaining methods, it’d be neat to have something that was passed
in the string and returned a ‘decorated’ version, e.g.

pp = ary.join(“,”).decorate {|s| “[#{s}]”}

You mean, equivilent to:

s = ary.join(", ")
pp = “[#{s}]”

Which you would probably be better off writing as:

pp = “[#{ary.join(', ')}]”

And of course if you want the other way around:

pp = ary.map { |s| “[#{s}]” }.join(", ")

If you enjoy playing with blocks, you can do:

pp = ary.join(", ").map { |s| “[#{s}]” }.to_s

Perhaps setting $/ beforehand if you’re going to be dealing with
newlines.

attrib = title.capitalize.decorate {|t| “\t – #{author[t]},"#{t}"”}

attrib = “\t – #{author[t = title.capitalize]},"#{t}"”

(n*100).to_s.decorate {|p| “#{p}% done”}

This makes about as much sense as an .interpolate method:

“#{(n*100)}% done”

Not quite an RCR (it’s trivially implementable anyway) - just wanted
to see what people thought of the idea, and in particular if anyone
had nicer names to suggest.

Maybe uses for it can be found more generally – in a generic “perform
this block on myself” method?

def Object.perform
yield self
end

t = title.capitalize.perform { |t| “\t – #{author[t]}, "#{t}"” }

Or more likely:

t = books.genre[genre].first.perform { |b| “#{b.title.capitalize}: #{b.author}” }

But you’re still basically replacing “b = " with " { |b| }” and adding
some overhead for the block. Can you think of anything more worthwhile?

The best I can come up with is:

titleFormatter = proc { |b| “#{b.title.capitalize}: #{b.author}” }
t = books.genre[genre].first.perform(titleFormatter)

But that’s just an inverted (and longer) way of doing:

t = titleFormatter.call(books.genre[genre].first)

I’m still not seeing much point :slight_smile:

···


Thomas ‘Freaky’ Hurst - freaky@aagh.net - http://www.aagh.net/

When chaining methods, it’d be neat to have something that was passed
in the string and returned a ‘decorated’ version, e.g.

pp = ary.join(“,”).decorate {|s| “[#{s}]”}

I assume you want ‘pp’ to contain: “(1),(2),(3)” ?

No, “[1,2,3]”, defining decorate merely as

class String
def decorate
yield self
end
end

If so then I don’t think your example will work:
1st you join the array into a string
2nd you decorate each array-element (impossible).

No, I want to decorate the string, as a prettier way of doing

pp = “[” << ary.join(“,”) << “]”

It works a bit like ‘collect’ or ‘map’

how about

title.capitalize.map {|t| “\t – #{author[t]},"#{t}"”}

No, String#each iterates over its characters.

martin

···

Simon Strandgaard 0bz63fz3m1qt3001@sneakemail.com wrote:

On Sun, 22 Jun 2003 06:46:00 +0000, Martin DeMello wrote:

No, simply

class String
def decorate
yield self
end
end

martin

···

ts decoux@moulon.inra.fr wrote:

pp = ary.join(“,”).decorate {|s| “[#{s}]”}
attrib = title.capitalize.decorate {|t| “\t – #{author[t]},"#{t}"”}
(n*100).to_s.decorate {|p| “#{p}% done”}

Something like this ?

svg% ri String#%

Thomas Hurst tom.hurst@clara.net wrote in message

I’m still not seeing much point :slight_smile:

Just that I prefer the look of

foo.bar.baz.perform {|a| f(a)} # perform is a nice generalisation to
objects

to either

a = foo.bar.baz
a = f(a)

or (specifically for strings)

“gunk #{foo.bar.baz} moregunk”

because I frequently think of the decoration as the last step in a
series of transformations, not as a sort of Cish main() that calls the
other transformations.

The reason I limited it to strings is that I seldom do {a = f(a)} type
transformations for anything other than strings and numbers, and
number manipulations I think of in a more functional than OO syntax
anyway.

martin

titleFormatter = proc { |b| “#{b.title.capitalize}: #{b.author}” }
t = books.genre[genre].first.perform(titleFormatter)

It’s basically the “with(object) do … end” pattern, isn’t it?

Ari

ts decoux@moulon.inra.fr wrote in message news:200306221301.h5MD1sC26632@moulon.inra.fr

Something like this ?

svg% ri String#%

Guy, I have to ask… why does your prompt say “svg”?

— SER

When chaining methods, it’d be neat to have something that was passed
in the string and returned a ‘decorated’ version, e.g.

pp = ary.join(“,”).decorate {|s| “[#{s}]”}
[snip]

No, I want to decorate the string, as a prettier way of doing

pp = “[” << ary.join(“,”) << “]”

OK… My assumption was wrong… I couldn’t see which kind of
output you wanted… I understand now.

It works a bit like ‘collect’ or ‘map’

how about

title.capitalize.map {|t| “\t – #{author[t]},"#{t}"”}

No, String#each iterates over its characters.

If I do #map on a string… then it looks like this:

irb
irb(main):001:0> x = “abcdef”
=> “abcdef”
irb(main):002:0> puts x.map {|y| “<#{y}>”}

=> nil
irb(main):003:0>

···

On Sun, 22 Jun 2003 16:35:32 +0000, Martin DeMello wrote:

Simon Strandgaard 0bz63fz3m1qt3001@sneakemail.com wrote:

On Sun, 22 Jun 2003 06:46:00 +0000, Martin DeMello wrote:


Simon Strandgaard

Or … yes; that’s exactly what sprintf is for.

ary = %w{eight nine ten}
puts “[%s]” % ary.join(“,”)
n=3
puts “%s%% done” % (n*100)

#-> [eight,nine,ten]
#-> 300% done

The 'attrib example you give is just as simple but I
haven’t got the dataset to resolve all the variables.

daz

···

“Martin DeMello” martindemello@yahoo.com wrote:

ts decoux@moulon.inra.fr wrote:

pp = ary.join(“,”).decorate {|s| “[#{s}]”}
attrib = title.capitalize.decorate {|t| “\t – #{author[t]},"#{t}"”}
(n*100).to_s.decorate {|p| “#{p}% done”}

Something like this ?

svg% ri String#%

No, simply

class String
def decorate
yield self
end
end

martin

Guy, I have to ask... why does your prompt say "svg"?

moulon% host svg
svg.moulon.inra.fr has address 138.102.114.196
moulon%

Guy Decoux

Hi,

···

At Fri, 27 Jun 2003 00:16:32 +0900, Sean Russell wrote:

svg% ri String#%

Guy, I have to ask… why does your prompt say “svg”?

Super Veteran Geek?


Nobu Nakada

I wrote:

n=3
puts “%s%% done” % (n*100)

#-> 300% done

Which is just about my level of numeracy.

n=0.74832
puts “%3.0d%% done” % (n*100)

might be better in the real world.

#-> 74% done

Doh! Of course, it’s per line, not per character. Was thinking of
each_byte.

ruby -e ‘p “line 1\nline 2”.map {|i| “<<#{i}>>”}’
[“<<line 1\n>>”, “<<line 2>>”]

martin

···

Simon Strandgaard 0bz63fz3m1qt3001@sneakemail.com wrote:

If I do #map on a string… then it looks like this:

irb
irb(main):001:0> x = “abcdef”
=> “abcdef”
irb(main):002:0> puts x.map {|y| “<#{y}>”}

=> nil
irb(main):003:0>

pp = ary.join(“,”).decorate {|s| “[#{s}]”}
attrib = title.capitalize.decorate {|t| “\t – #{author[t]},"#{t}"”}
(n*100).to_s.decorate {|p| “#{p}% done”}

Something like this ?

svg% ri String#%

No, simply

class String
def decorate
yield self
end
end

martin

Or … yes; that’s exactly what sprintf is for.

ary = %w{eight nine ten}
puts “[%s]” % ary.join(“,”)
n=3
puts “%s%% done” % (n*100)

#-> [eight,nine,ten]
#-> 300% done

The 'attrib example you give is just as simple but I
haven’t got the dataset to resolve all the variables.

daz

···

daz dooby@d10.karoo.co.uk wrote:

“Martin DeMello” martindemello@yahoo.com wrote:

ts decoux@moulon.inra.fr wrote:

Or … yes; that’s exactly what sprintf is for.

ary = %w{eight nine ten}
puts “[%s]” % ary.join(“,”)
n=3
puts “%s%% done” % (n*100)

#-> [eight,nine,ten]
#-> 300% done

Sorry 'bout the blank post, let me try that again.

I wasn’t saying that there was no other way to do it, just that there
was no other pretty way. sprintf isn’t nearly as pretty as #{}

martin

···

daz dooby@d10.karoo.co.uk wrote: