user3116998
user3116998

Reputation: 7

Post issue with sinatra

Following this tutorial to create the route for the POST:

post '/secret' do  
  params[:secret].reverse  
end

When I view this on the local server I get my secret message in reverse. But if I want to print another line, below the reverse line, the output gets all messed up on the localhost:9393.

post '/secret' do  
  p params[:secret].reverse
  p params[:secret].reverse
end

Any ideas why, in the second block of code, only one line of the reversed secret shows up on my output after inputting the secret in the form on the main page? I'm looking to write more complex code but it seems like it's only printing the last line. Is this a Sinatra thing?

Upvotes: 0

Views: 251

Answers (3)

Amadan
Amadan

Reputation: 198556

Oh, I see. You're using p.

Unlike PHP, Sinatra does not capture standard output. Rather, what is returned as the content .of the page is what is returned from the function.

In the first example, you return the result of reverse.

In the first example, you return nil, which is the result of the second p call.

If you want to return both reverses, you need to construct a string that contains them both:

post '/secret' do  
  "#{params[:secret].reverse}\n#{params[:secret].reverse}"
end

Upvotes: 1

Patrick Oscity
Patrick Oscity

Reputation: 54734

It's just how Sinatra works. The return value of the post block is sent as response. The return value of the block is always the return value of the last statement inside the block. So your p is actually useless, it will only print the secret to the log. It just happens that p returns the value it was passed after printing it, so you still see one line because that is the return value of the block. If you actually want to return a response that contains the line twice, you have to build a single string that contains two lines. There are many ways to do this, here are some:

# use string interpolation to create a string that
# contains reversed_secret, followed by a newline,
# then again followed by reversed_secret
post '/secret' do  
  reversed_secret = params[:secret].reverse
  "#{reversed_secret}\n#{reversed_secret}"
end

# use an array and join the values with a newline
post '/secret' do
  reversed_secret = params[:secret].reverse
  [reversed_secret, reversed_secret].join("\n")
end

# "print" individual lines to a StringIO object
# and read the resulting string afterwards
post '/secret' do
  result = StringIO.new

  reversed_secret = params[:secret].reverse

  result.puts reversed_secret
  result.puts reversed_secret

  result.string
end

Whatever works best for you.

Upvotes: 1

Landstander
Landstander

Reputation: 476

In your first example you're seeing your secret in reverse because Sinatra is handed the reversed string from the block and displays it.

In your second bit of code you're printing the reversed strings to the local output, which is where you'd expect to see the logs displayed. You're seeing a messed up string because the result of p params[:secret].reverse is not something Sinatra apparently wants to display correctly. Sinatra will fall back to trying to display the value returned from a route block if no other output had already been built up.

The next section of the tutorial you're following covers Views and Templates. Those are what you'll use to output a webpage.

Upvotes: 2

Related Questions