Cgi question

Hi, the following code results in NoMethodError, when being executed as a cgi script.

The reason is the line "+ cgi.b {"hello world in bold"}" at the bottom.

Can anybody explain me, what's happening here?
The preceding block simply returns a (html) string, containing a form, which is concatenated with "<b>hello world in bold</b>"

Do you have any idea?

thanks Boris

#!/usr/bin/ruby

require "cgi"

cgi=CGI.new("html4")

cgi.out {

  CGI.pretty(
   cgi.html{
    cgi.head{
     cgi.title{ "testpage" }
    } +
    cgi.body{
     cgi.form{
      cgi.table( {'border' => '1'} ){
       cgi.tr {
        cgi.td{ "hello"} +
        cgi.td {"world"}
       } # end tr
      } # end table
     } # end form
  + cgi.b {"hello world in bold"}
    } # end head
   } # end html
  ) # end CGI#pretty

} # end cgi.out

···

#############################################################

the error message:

# ./test.rb
(offline mode: enter name=value pairs on standard input)
../test.rb:24: undefined method `+@' for "<B>hello world in bold</B>":String (NoMethodError)
         from ./test.rb:15:in `body'
         from ./test.rb:15
         from ./test.rb:11:in `html'
         from /usr/lib/ruby/1.8/cgi.rb:1653:in `html'
         from ./test.rb:11
         from ./test.rb:8:in `out'
         from ./test.rb:8

Boris Glawe said:

Hi, the following code results in NoMethodError, when being executed as a
cgi
script.

The reason is the line "+ cgi.b {"hello world in bold"}" at the bottom.

You are attempting to call the unary operator + on cgi.b, which returns a
string. In Ruby's internals the unary + is actually the +@ method. This
code works:

require "cgi"

cgi=CGI.new("html4")

cgi.out {

CGI.pretty(
  cgi.html{
   cgi.head{
    cgi.title{ "testpage" }
   } +
   cgi.body{
    cgi.form{
     cgi.table( {'border' => '1'} ){
      cgi.tr {
       cgi.td{ "hello"} +
       cgi.td {"world"}
      } # end tr
     } # end table
    } +# end form <--NOTE WHERE THE PLUS IS
   cgi.b {"hello world in bold"}
   } # end head
  } # end html
) # end CGI#pretty

} # end cgi.out

Ryan

Ryan Leavengood wrote:

Boris Glawe said:

Hi, the following code results in NoMethodError, when being executed as a
cgi
script.

The reason is the line "+ cgi.b {"hello world in bold"}" at the bottom.

You are attempting to call the unary operator + on cgi.b, which returns a
string. In Ruby's internals the unary + is actually the +@ method. This
code works:

Thanks a lot!!

This is an ugly pitfall, as ruby usually grants a lot of freedom in layout.

greets Boris

Boris Glawe said:

Thanks a lot!!

This is an ugly pitfall, as ruby usually grants a lot of freedom in
layout.

I agree that in most cases Ruby grants a lot of freedom, but I don't think
this is too ugly of a pitfall. There needs to some way of indicating
positive and negative numbers, and Ruby just makes things more flexible by
making that a method. You can make your own classes that use it:

class Book
  attr_reader :name, :good
  def initialize(name)
    @name = name
    @good = nil
  end

  def +@
    @good = true
  end

  def -@
    @good = false
  end

  def to_s
    "#@name is #{@good == nil ? 'unrated' : @good ? 'good' : 'bad'}"
  end
end

book = Book.new('Da Vinci Code')
puts book
+book
puts book
-book
puts book
__END__

Output:
Da Vinci Code is unrated
Da Vinci Code is good
Da Vinci Code is bad

Though it may not be all that useful in most cases.

Ryan