patternrubyMinor
String substitutions in ruby and coding style
Viewed 0 times
substitutionscodingstylerubyandstring
Problem
I wrote a short ruby script to generate various screenshots, and event though I am not completely new to ruby I rarely use it.
Full script (41 LOC): https://gist.github.com/1229115
The string substitutions irritate me. They don't look quite right - much too ugly for a beautiful and concise language like ruby. Am I overdoing it? What alternatives are there?
Here is the lines I am concerned about (for context, please take a look at the gist):
Just to illustrate the script, the output usually looks like:
Full script (41 LOC): https://gist.github.com/1229115
The string substitutions irritate me. They don't look quite right - much too ugly for a beautiful and concise language like ruby. Am I overdoing it? What alternatives are there?
Here is the lines I am concerned about (for context, please take a look at the gist):
# assemble file name
fname = "#{directory}/#{prefix}-#{timestamp}-#{commit}-#{size[:width]}x#{size[:height]}.png"
# create command line stuff
call = "#{macruby_exe} #{snapper} \
--width #{size[:width]} --height #{size[:height]} #{url} #{fname}"
# now call it
system call
# just to show the progress (and the file sizes)
puts "#{fname} (#{File.size?(fname) / 1024}kB)"Just to illustrate the script, the output usually looks like:
screenies/screenshot-1316535022-0b5c7967887481deb17bcd9039cd3fe0ac4540d4-640x960.png (95kB)
screenies/screenshot-1316535022-0b5c7967887481deb17bcd9039cd3fe0ac4540d4-800x480.png (62kB)
screenies/screenshot-1316535022-0b5c7967887481deb17bcd9039cd3fe0ac4540d4-800x600.png (78kB)
^ ^ ^ ^ ^
| | | | ________|______
| | | | | |
directory prefix timestamp commit size[:width] x size[:height]Solution
There are other ways you could write this but I'm not sure if you'd find any of them cleaner. One option is plain old
You could shorten it a little by giving
...and perhaps create other convenience methods along the same lines. But still, very small gains.
Another option would be to make your own super-small template engine, something like this:
So, that's kinda nice, but is it really worth it? Not for me, but I guess if you really hate "
sprintf. For example:# assemble file name
fname = sprintf("%s/%s-%i-%s-%ix%i.png", directory, prefix, timestamp,
commit, size[:width], size[:height])You could shorten it a little by giving
size its own to_s method:class << size; def to_s; "#{self[:width]}x#{self[:height]}" end end
fname = sprintf("%s/%s-%i-%s-%s.png", directory, prefix, timestamp,
commit, size)...and perhaps create other convenience methods along the same lines. But still, very small gains.
Another option would be to make your own super-small template engine, something like this:
def tiny_subst template, bndg
param_exp = /:(\w+)[^\w:]+/i
tmpl_params = template.scan(param_exp).flatten
proc {
out_str = template.clone
tmpl_params.reduce(out_str) do |str, p|
str.gsub ":#{p}", eval(p, bndg).to_s unless p.empty?
end
}
end
tmpl = ':directory/:prefix-:timestamp-:commit-:size.png'
subber = tiny_subst(tmpl, binding)
directory = 'screenies'
prefix = 'screenshot'
timestamp = Time.now.to_i
commit = '0b5c7967887481deb17bcd9039cd3fe0ac4540d4'
size = '640x960'
subber.yield # => screenies/screenshot-1316535022-0b5c7967887481deb17bcd9039cd3fe0ac4540d4-640x960.png
commit = 'foobarbazquux'
size = '9000x9000'
subber.yield # => screenies/screenshot-1316535022-foobarbazquux-9000x9000.pngSo, that's kinda nice, but is it really worth it? Not for me, but I guess if you really hate "
#{this}" it might be.Code Snippets
# assemble file name
fname = sprintf("%s/%s-%i-%s-%ix%i.png", directory, prefix, timestamp,
commit, size[:width], size[:height])class << size; def to_s; "#{self[:width]}x#{self[:height]}" end end
fname = sprintf("%s/%s-%i-%s-%s.png", directory, prefix, timestamp,
commit, size)def tiny_subst template, bndg
param_exp = /:(\w+)[^\w:]+/i
tmpl_params = template.scan(param_exp).flatten
proc {
out_str = template.clone
tmpl_params.reduce(out_str) do |str, p|
str.gsub ":#{p}", eval(p, bndg).to_s unless p.empty?
end
}
end
tmpl = ':directory/:prefix-:timestamp-:commit-:size.png'
subber = tiny_subst(tmpl, binding)
directory = 'screenies'
prefix = 'screenshot'
timestamp = Time.now.to_i
commit = '0b5c7967887481deb17bcd9039cd3fe0ac4540d4'
size = '640x960'
subber.yield # => screenies/screenshot-1316535022-0b5c7967887481deb17bcd9039cd3fe0ac4540d4-640x960.png
commit = 'foobarbazquux'
size = '9000x9000'
subber.yield # => screenies/screenshot-1316535022-foobarbazquux-9000x9000.pngContext
StackExchange Code Review Q#4927, answer score: 5
Revisions (0)
No revisions yet.