1

I have a ruby variable created from a complex code , But I am unable to replace the variable declared inside my main variable . Here is an example , it may be simple but I could not able to change main variable declaration procedure.

irb(main):065:0> p msg
"My name is \#{name}"
irb(main):066:0> puts name
Foo
irb(main):067:0> puts msg
My name is #{name}
irb(main):068:0> puts "#{msg}"
My name is #{name}

I want an output like "My name is Foo" ; That needs to be achieved considering I can't control content format of variable 'msg'

3
  • Is msg a simple String, or is it a custom class? Commented Apr 22, 2020 at 7:23
  • Consider 'msg' is a simple variable , but It passed from a different procedure , So I cant change the declaration format . Commented Apr 22, 2020 at 7:43
  • I understand that you cannot control msg. That means you cannot use string interpolation at all. But is there any specification on how msg will look like? Like it contains always \#{name}? Or is it possible that msg might have a totally different format (like correct string interpolation) or different variables names (like fullname)? Commented Apr 22, 2020 at 7:43

2 Answers 2

2

You could build your own String class with a substitution at runtime.

class StringInterpollator < String
  def replace(bind)
    gsub(/\\*#\{(\w+)\}/) do |m|
      eval($1, bind)
    end
  end
end

msg = 'My name is \#{name}'
name = "Foo"

StringInterpollator.new(msg).replace binding #My name is Foo

EDIT: here a version that accepts both local variables as instance variables

class StringInterpollator < String
  def replace(bind)
    gsub(/\\*#\{?([\w@]+)\}?/){ |m| eval($1, bind)}
  end
end
Sign up to request clarification or add additional context in comments.

3 Comments

The backslash isn't in the string in the question. See the puts msg output.
Hi, If I pass the instance variable like #{@name}, it's not working. Should I send something else instead of binding in this case?
puts wil not show the \, p does. Instance variables behave differently, eg they don't need the curly brackets, published a version that handles them both
0

One simple approach is to use string substitution with the sub method like this

name = "Foo"
msg.sub('#{name}', name) # => "My name is Foo" 

However, this assumes that msg always contains the text \#{name}

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.