0

I have following code:

date_time = Time.now.strftime('%Y%m%d%H%M%S')
name = "builder-#{date_time}"   # builder-20150923125450

if some_condition
  name.sub!("#{date_time}", "one-#{date_time}") # builder-one-20150923125450
end

Above code is working fine. But I think it could be better as I feel like I am repeating #{date_time} twice here.

I have heard of regex capture and replace. Can we use it here? If yes, how?

8
  • You mean you cannot change the code that creates the string name, and you have to modify it? Commented Sep 23, 2015 at 8:24
  • Why don't you like this solution (in question)? Commented Sep 23, 2015 at 8:25
  • 2
    An array could help: ['builder', ('one' if cond), date_time].compact.join('-') Commented Sep 23, 2015 at 8:50
  • 2
    @Stefan I would do: ['builder', *('one' if cond), date_time].join('-'). Commented Sep 23, 2015 at 8:52
  • 1
    @sawa excellent use of *! Commented Sep 23, 2015 at 9:08

3 Answers 3

3

To utilize capturing mechanism, you need to use round brackets round a subpattern that you would like to refer to using a back-reference in the replacement string.

Here is an example:

date_time = Time.now.strftime('%Y%m%d%H%M%S')
name = "builder-#{date_time}"
puts name.sub(/^([^-]*-)/, "\\1one-")

See IDEONE demo

The ^([^-]*-) matches and captures all characters other than - from the beginning of the string (^) and a hyphen, and then we refer to the text with \\1 in the replacement string.

Refer to Use Parentheses for Grouping and Capturing at Regular-Expressions.info for more details.

A more optimal way is using a ternary operator when initializing name variable:

a = 1
date_time = Time.now.strftime('%Y%m%d%H%M%S')
name = "builder-" + (some_condition ? "one-" : "") + "#{date_time}"

IDEONE demo

Sign up to request clarification or add additional context in comments.

7 Comments

@Downvoter: Any hint on what is wrong? I have heard of regex capture and replace. Can we use it here? If yes, how? - I guess my answer addresses that.
Accepting for this solution "name.sub(/^([^-]*-)/, "\\1one-")" as one is also variable here and need to be interpolated at some time. Please remove other optimal way to be precise with solution.
How can anything be "more optimal" than something else? "Better", yes.
Thanks anyway. I have less grip on regex :)
@ram: I added that ternary operator option for the downvoters. I think they did it because I suggested the regex.
|
1

Strategy one - precalculate the prefix:

date_time = Time.now.strftime('%Y%m%d%H%M%S')
prefix    = some_condition ? 'builder-one-' : 'builder-'
name      = "#{prefix}#{date_time}"

The string 'builder-' is repeated twice here. Obviously, you can DRY it even more, but it's an overkill IMHO.


Strategy two - use a lookahead:

date_time = Time.now.strftime('%Y%m%d%H%M%S')
name      = "builder-#{date_time}"

name.sub!(/(?=#{date_time})/, "one-") if some_condition

Now date_time appears only twice. I wouldn't say it's a great improvement. I wouldn't say there is much of a problem to begin with.

Comments

0
"builder-" + ("one-" if some_condition).to_s + date_time

date_time = "right now"

some_condition = true
"builder-" + ("one-" if some_condition).to_s + date_time
  #=> "builder-one-right now"

some_condition = false
"builder-" + ("one-" if some_condition).to_s + date_time
 #=> "builder-right now"   

Note that:

("one-" if false).to_s #=> nil.to_s => ""

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.