I am a beginner in Ruby. Could someone help me with this?
I want to call a method within ""
def callme
"this string" # this is usually a path that I want to source from a single location
end
v= "string + callme "
how do I call the function within quotes here? The quotes are essential for my code.
You can use string interpolation / concatenation:
def hi
'Hello'
end
def world
'World'
end
# Concatenation
hi + ' ' + world #=> "Hello World"
# Interpolation
"#{hi} #{world}" #=> "Hello World"
See this answer for more details
If I understand correctly, what you are looking for is string interpolation. The syntax for this is #{...}, like so:
v= "string + #{callme} "
This sets the variable v to "string + this string ".
Reference
Related
I'm trying to concatenate a constant into a string but I'm getting syntax error, unexpected unary+, expecting end' (SyntaxError)`
This is an example of what I have to do:
NAME = "Jane"
def a_function
s = 'Hi' + NAME +' !'
puts s
end
I know you can do "Hi #{NAME}!" but in my case the string has to be with single quotes.
How can I achieve this?
You are missing a space between + and ' !'.
This is a special case of confusing Ruby, because a single expression like +x is actually a valid unary expression meaning just x, the same way as +1 means 1.
Because of this it's likely Ruby is interpreting your expression a + b +c, as a + b c, which is invalid, and hence the error.
The fix:
s = 'Hi ' + NAME + ' !'
^------ Note the space here!
For this code:
def bonjour(*noms)
noms.each{|i| puts 'bonjour #{i}'}
end
bonjour('Marc','pierre')
I get this output:
bonjour #{i}
bonjour #{i}
I don't understand why my interpolation does not work. Could you help?
You need to use double quotes " instead of single quotes ' to use string interpolation:
def bonjour(*noms)
noms.each { |i| puts "bonjour #{i}" }
end
I am trying to use a custom method with here-doc and want to pass parameter (there is no business case, I am merely trying to learn ruby). Is there a way to pass parameter in this case? This is what I have so far.
Simple method, just works fine.
def meth1
self.upcase
end
str1 = <<MY.meth1
i am a small case string
MY
# "I AM A SMALL CASE STRING\n"
Now, I thought let us drop some parameters and tried different variations and irb gives me a blank stare.
#variation 1
def meth2( <<EOF1, <<EOF2 )
EOF1.upcase + "..." + EOF2.downcase
end
str2 = <<MY.meth2
some string
EOF1
ANOTHER STRING
EOF2
MY
My guess is that this is what you are trying to do:
def meth2(str1, str2)
str1.upcase + "..." + str2.downcase
end
str2 = meth2(<<EOF1, <<EOF2)
some string
EOF1
ANOTHER STRING
EOF2
str2 # => " SOME STRING\n... another string\n"
If you don't intent to indent, see here. ← See my play with words here?
try something along the lines of
something = "bananas"
str = <<EOF
this has some #{something} in!
EOF
Try something like this:
def meth2( item1, item2 )
item1.upcase + "..." + item2.downcase
end
str2 = meth2 <<EOF1, <<EOF2
some string
EOF1
ANOTHER STRING
EOF2
The problem you are having is due to not fully understanding how heredoc-style string literals work. The <<DELIMITER part just is telling the parser to get it's string data from the lines that follow it. If there is more than one <<DELIMITER on a line, then they stack, and are read in in sequence. So, in this case, the code above is exactly equivalent to:
def meth2( item1, item2 )
item1.upcase + "..." + item2.downcase
end
str2 = meth2 " some string\n", " ANOTHER STRING\n"
Most importantly, there is no way to build a heredoc into a function like you were trying to do there... They can only be used in the same places and manner that other String literals, such as "double quoted" or 'single quoted' literals, can be used.
Problem
In a source file, I have a large number of strings. Some with interpolation, some with special symbols and some with neither.
I am trying to work out if I can replace the simple strings' double quotes with single quotes whilst leaving double quotes for the interpolated and special symbol strings. I would then run this conversion on one or more source code files.
I imagine there is probably a nice regex for this, but I can't quite formulate it.
Example - Code
Imagine the following code:
def myfunc(var, var2 = "abc")
s = "something"
puts "a simple string"
puts "string with a single ' quote"
puts "string with a newline \n"
puts "my #{var}"
end
Example - Result
I would like to turn it into this:
def myfunc(var, var2 = 'abc')
s = 'something'
puts 'a simple string'
puts "string with a single ' quote"
puts "string with a newline \n"
puts "my #{var}"
end
If anyone has any ideas I'd be very grateful!
Assuming that you can read your string from your file by yourself into an array strings:
strings = [ "\"a simple string\"",
"\"string with a single ' quote\"",
"\"string with a newline \n\""
"\"my \#{var}\"" ]
then we would eval them to see how they behave:
$SAFE = 4
single_quoted_when_possible = strings.map { |double_quoted|
begin
string = eval( double_quoted ) # this string, as Ruby sees it
raise unless string.is_a? String
raise unless '"' + string + '"' == double_quoted
rescue
raise "Array element is not a string!"
end
begin
raise unless eval( "'#{string}'" ) == string
"'#{string}'"
rescue
double_quoted
end
}
And that SAFE level 4 is just woodoo, just an acknowledgement from me that we are doing something dangerous. I do not know to what extent it actually protects against all dangers.
In your particular case, you can create a Regexp heuristic, relying on hope that nobody will write "evil" strings in your code, such as /= *(".+") *$/ or /\w+ *\(* *(".+") *\)* *$/. That heuristic would extract some string suspects, to which you could further apply the method I wrote higher above. But I would still have human look at each replacement, and run tests on the resulting code afterwards.
I want to convert the string:
"{john:123456}"
to:
"<script src='https://gist.github.com/john/123456.js'>"
I wrote a method that works, but it is very stupid. It is like this:
def convert
args = []
self.scan(/{([a-zA-Z0-9\-_]+):(\d+)}/) {|x| args << x}
args.each do |pair|
name = pair[0]
id = pair[1]
self.gsub!("{" + name + ":" + id + "}", "<script src='https://gist.github.com/#{name}/#{id}.js'></script>")
end
self
end
Is there a way to do this just like the cool_method below?
"{john:123}".cool_method(/{([a-zA-Z0-9\-_]+):(\d+)}/, "<script src='https://gist.github.com/$1/$2.js'></script>")
That cool method is gsub. You were so close! Just change the $1 and $2 to \\1 and \\2
http://ruby-doc.org/core-2.0/String.html#method-i-gsub
"{john:123}".gsub(/{([a-zA-Z0-9\-_]+):(\d+)}/,
"<script src='https://gist.github.com/\\1/\\2.js'></script>")
I would do
def convert
/{(?<name>[a-zA-Z0-9\-_]+):(?<id>\d+)}/ =~ self
"<script src='https://gist.github.com/#{name}/#{id}.js'></script>"
end
Please see http://ruby-doc.org/core-2.0/Regexp.html#label-Capturing for more details.
s = "{john:123456}".scan(/\w+|\d+/).each_with_object("<script src='https://gist.github.com") do |i,ob|
ob<< "/" + i
end.concat(".js'>")
p s #=> "<script src='https://gist.github.com/john/123456.js'>"
That looks like a JSON string, so, as #DaveNewton said, treat it as one:
require 'json'
json = '{"john":123456}'
name, value = JSON[json].flatten
"<script src='https://gist.github.com/#{ name }/#{ value }.js'></script>"
=> "<script src='https://gist.github.com/john/123456.js'></script>"
Why not treat it as a string and use a regular expression on it? Because JSON isn't a simple format for parsing via regular expressions, which can cause errors as the values change or the data string gets more complex.