For the following code, why does only "World" gets printed
get '/' do
"Hello"
"World"
end
This has nothing to do with sinatra itself. It just uses the return value of the block and in ruby the return value is the last evaluated expression, which in your case is "World". This might work for you:
get '/' do
r = "Hello"
r += "World"
end
In this case you add as many string values to r as you want and the last expression would return the complete string "HelloWorld".
Correct me if I'm wrong, but I do believe in plain ruby, the last line evaluated is what gets returned.
Tomas correctly answered your question, but one way to do what I think you're meaning to do (output multiple lines), you could use:
get '/' do
output =<<EOS
Hello
World
EOS
output
end
You could use a line break char to separate lines..
get '/' do
"Hello\nWorld"
end
Don't confuse your controller with your view.
What you're probably looking for is this:
get '/' do
haml :hello_world
end
And then in views/hello_world.haml:
Hello
World
I agree with Matt.
If you want you can use that method with one file too.
get '/' do
erb :hello_world
end
__END__
##hello_world
hello
world
I just use puts inside my controller to get some debug printed to STDOUT.
Related
I have a controller with PUT method:
class UtilsController < ActionController::API
def update_user_password
email = params[:email]
password = params[:password]
new_password = params[:new_password]
puts("'#{password}'")
end
end
and use openapi/javascript and Postman to send password nRP63P#$
and in console it logs nRP63P\#$
Is params of controller escaped, and how to get real value? URI.unescape?
Reference is welcome.
Thank you.
Please compare output with p and puts
password = 'nRP63P#$'
p password # will print "nRP63P\#$"
puts password # will print nRP63P#$
You can unescape value with tools of Rack
I think you were looking exactly for this Rack::Utils#unescape method.
So in your case it will be
unescaped_password = Rack::Utils.unescape(params[:password])
Keep in mind that, ruby output by default escapes some special chars # is one of them, cause it is indicator of comment, in order to evaluate further code ruby escapes it. So to verify yourself you need to write it to STDOUT or to a file.
puts unescaped_password
File.open('test.txt', 'w') { |f| f.write(unescaped_password)
and then inspect your result.
Do not use Kernel#pp or Kernel#p or String#inspect cause all of them will print values with special chars escaped by ruby itself and can mislead you.
I'm still learning Ruby and I'm practicing my get routes and post requests, User sign in, log in, etc for a basic website and I came across a "slug" method:
def slug
self.username.strip.downcase.gsub(" ","-")
end
I tried using irb to try and figure out what gsub is doing:
"hello".gsub(" ","-")
but it just gave me:
"hello"
And I tried using it on a array, but that didn't work as well.
But my question is what exactly is gsub doing here? What is gsub in general? What is the outcome of this method?
Thanks in advance!
In Ruby, Gsub is a method that can be called on strings. It replaces all instances of a substring with another one inside the string.
Sub is short for "substitute," and G stands for "global." Think of Gsub like a "replace all" function.
The general pattern is str.gsub("target string", "replacement string").
In your example, nothing changes because there are no spaces in the string "hello" that can be replaced with a "-" character.
"hello".gsub(" ","-")
The following example replaces the "!" in "hello!" with ", world", printing "hello, world!"
puts "hello!".gsub("!",", world!")
The following example replaces every instance of "!" in "!!!" with "123", printing "123123123"
puts "!!!".gsub("!", "123")
Is there a method (perhaps in some library from Rails) or an easy way that capitalizes the first letter of a string without affecting the upper/lower case status of the rest of the string? I want to use it to capitalize error messages. I expect something like this:
"hello iPad" #=> "Hello iPad"
There is a capitalize method in Ruby, but it will downcase the rest of the string. You can write your own otherwise:
class String
def capitalize_first
(slice(0) || '').upcase + (slice(1..-1) || '')
end
def capitalize_first!
replace(capitalize_first)
end
end
Edit: Added capitalize_first! variant.
Rather clumsy, but it works:
str = "hello IiPad"
str[0] = str[0].upcase #or .capitalize
Thanks to other answers, I realized some points that I need to be aware of, and also that there is no built in way. I looked into the source of camelize in Active Support of Rails as hinted by Vitaly Zemlyansky, which gave me a hint: that is to use a regex. I decided to use this:
sub(/./){$&.upcase}
Try this
"hello iPad".camelize
I have a file containing substituted variables (#{...}) and I would like to copy it into another file, with the variables substituted by their values.
Here's what I have
file = File.open(#batch_file_name, "w+")
script=File.open("/runBatch.script","r")
script.each do |line|
file.puts(line)
end
But this is apparently not the right way to do that. Any suggestion ?
Instead of #{...} in your file use ERB files.
No, this isn't the right way to do it. You can't expect Ruby to magically interpret any #{} it encounters anywhere in your data as variable interpolation. This would (amongst other terrible side effects) yield massive security problems everywhere.
If you want to interpolate data into a string you'll need to eval it, which has its own security risks:
str = 'The value of x is #{x}'
puts str # The value of x is #{x}
x = "123"
puts eval "\"#{str}\"" # Thje value of x is 123
It's not clear which variables you're trying to interpolate into your data. This is almost certainly the wrong way to go about doing whatever it is your doing.
Ok say you have a file named tmp.file that has the following text:
This is #{foobar}!
Then you can easily do the following:
str = ""
File.open("tmp.file", "r") do |f|
str = f.read
end
abc = "Sparta"
puts eval('"' + str + '"')
And your result would be This is Sparta!
But as already suggested you should go with a real template solution like ERB. Then you would use your files like views in Rails. Instead of This is #{foobar}. you would have This is <%= foobar %>.
Suppose I have:
foo/fhqwhgads
foo/fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf/bar
And I want to replace everything that follows 'foo/' up until I either reach '/' or, if '/' is never reached, then up to the end of the line. For the first part I can use a non-capturing group like this:
(?<=foo\/).+
And that's where I get stuck. I could match to the second '/' like this:
(?<=foo\/).+(?=\/)
That doesn't help for the first case though. Desired output is:
foo/blah
foo/blah/bar
I'm using Ruby.
Try this regex:
/(?<=foo\/)[^\/]+/
Implementing #Endophage's answer:
def fix_post_foo_portion(string)
portions = string.split("/")
index_to_replace = portions.index("foo") + 1
portions[index_to_replace ] = "blah"
portions.join("/")
end
strings = %w{foo/fhqwhgads foo/fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf/bar}
strings.each {|string| puts fix_post_foo_portion(string)}
I'm not a ruby dev but is there some equivalent of php's explode() so you could explode the string, insert a new item at the second array index then implode the parts with / again... Of course you can match on the first array element if you only want to do the switch in certain cases.
['foo/fhqwhgads', 'foo/fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf/bar'].each do |s|
puts s.sub(%r|^(foo/)[^/]+(/.*)?|, '\1blah\2')
end
Output:
foo/blah
foo/blah/bar
I'm too tired to think of a nicer way to do it but I'm sure there is one.
Checking for the end-of-string anchor -- $ -- as well as the / character should do the trick. You'll also need to make the .+ non-greedy by changing it to .+? since the greedy version will always match right up to the end of the string, given the chance.
(?<=foo\/).+?(?=\/|$)