This isn't quite a hello-world, because I want to show how to use macros for building HTTP services.
First, we need to tell Ruby to load webrick module and bind class name into RLisp namespace (there is no automatic importing of constants, maybe there should me):
(ruby-eval "require 'webrick'") ; import module
(let HTTPServer (ruby-eval "WEBrick::HTTPServer"))
Now let's create the server object and tell it to bind to port 1337 instead of default port 80. Configuration is simply a hash table:
; Configure the server
(let config [Hash new])
[config set 'Port 1337]
; Tell the class to make us a server object
(let server (send HTTPServer 'new config))
Now we could basically send
mount_proc message to server object to bind a lambda to URL.
; Tell server to call our Hello World handler
(send server 'mount_proc "/hello"
(lambda (req res)
[res body= "<html><body><h3>Hello, world!</h3></body></html>"]
[res field_set "Content-Type" "text/html"]
)
)
But this is not very nice. Let's macro around this definition.
First let's make a macro that lets us bind more easily:
; Define a macro for HTML mounts
(defsyntax def-server-html-mount args
`(send ,[args get 0] 'mount_proc ,[args get 1]
(lambda (req res)
(send res 'field_set "Content-Type" "text/html")
(send res 'body= (do ,@(tl (tl args))))
(print res)
)
)
)
Now we can rewrite the original handler to:
; Tell server to call our Hello World handler
(def-server-html-mount server "/hello"
"<html><body><h3>Hello, world!</h3></body></html>"
)
The mount is as good as it gets, but we'd still rather have nice syntax for HTML.
So let's define a macro that creates html-generating functions:
; Define a macro for HTML tag function
(defsyntax def-html-tag (tagname)
`(defun ,tagname args
(+
"<" (send ',tagname to_s) ">"
[args join]
"</" (send ',tagname to_s) ">"
)
)
)
And define a few such functions:
(def-html-tag html)
(def-html-tag body)
(def-html-tag h3)
Could it be any more cute than that ?
(def-server-html-mount server "/hello2"
(html (body (h3 "Macros Greet you")))
)
Happy about the results, we start the server:
; Tell the server to go !
(send server 'start)
RLisp is available for download from
http://taw.github.io/rlisp/.
Previous posts about RLisp are
here [1] and
here [2].