Allow # {var} per line

I loaded the C # line {variable} with the links in it. How can I resolve these variables in a string like puts ?

 name="jim" str="Hi #{name}" puts str 

Instead of puts, I would like the result to be available for passing as a parameter or saving to a variable.

0
source share
5 answers

you could rate it

 name = "Patrick" s = 'hello, #{name}' s # => "hello, \#{name}" # wrap the string in double quotes, making it a valid interpolatable ruby string eval "\"#{s}\"" # => "hello, Patrick" 
+1
source

puts does not allow variables. The Ruby parser does when it creates a string. if you passed str to any other method, it would be the same as passing "Hi jim" since the interpolation has already been done.

+1
source

The line has a format option that displays as % . It can be used to pass arguments to a predefined string, as interpolation does.

 message = "Hello, %s" for_patrick = message % "Patrick" #=> "Hello, Patrick" for_jessie = message % "Jessie" #=> "Hello, Jessie" messages = "Hello, %s and %s" for_p_and_j = messages % ["Patrick", "Jessie"] #=> "Hello, Patrick and Jessie" 

It may not look like "Rubyish", but I believe that this is the functionality you are looking for.

So, if you have a line coming from somewhere that contains these placeholders, you can pass the values ​​as arguments like this:

 method_that_gets_hello_message % "Patrick" 

It will also allow you to accept only the expected values.

 message = "I can count to %d" message % "eleven" #=> ArgumentError: invalid value for Integer() 

There is a list on Wikipedia for possible placeholders for printf() , which should also work in Ruby.

+1
source

eval seems to be the only solution for this particular task. But we can avoid this dirty-unsafe-dishonest eval if we change the task a bit: we can resolve a non-local copy of the instance without eval using instance_variable_get :

 @name = "Patrick" @id = 2 # Test that number is ok @a_b = "oooo" # Test that our regex can eat underscores s = 'hello, #{name} !!#{id} ??#{a_b}' s.gsub(/#\{(\w+)\}/) { instance_variable_get '@'+$1 } => "hello, Patrick !!2 ??oooo" 

In this case, you can even use any other characters instead of #{} (for example, %name% , etc.), just changing the regex a bit.

But of course it all smells.

0
source

It looks like you want to create the basis for a template system that Ruby makes easy if you use String gsub or sub methods.

 replacements = { '%greeting%' => 'Hello', '%name%' => 'Jim' } pattern = Regexp.union(replacements.keys) '%greeting% %name%!'.gsub(pattern, replacements) => "Hello Jim!" 

You can also easily define a key as:

 replacements = { '#{name}' => 'Jim' } 

and use standard Ruby string interpolation #{...} , but I would recommend not using it again. Use something unique instead.

The advantage of this is that the target => replacement map can easily be placed in a YAML file or in a database table, and then you can replace them with other languages ​​or different user data. The sky is the limit.

Evaluation is also not in favor of this, it is only a replacement string. With a little creative use, you can implement macros:

 macros = { '%salutation%' => '%greeting% %name%' } replacements = { '%greeting%' => 'Hello', '%name%' => 'Jim' } macro_pattern, replacement_pattern = [macros, replacements].map{ |h| Regexp.union(h.keys) } '%salutation%!'.gsub(macro_pattern, macros).gsub(replacement_pattern, replacements) => "Hello Jim!" 
0
source

All Articles