Snippet request: Ruby Web Server written in under an hour

Rubies:

Plenty of blogs report D. Thomas and crew immersed some of you and let you
write a Web server in under an hour.

Nobody has left a result of this experience on the 'net. Could someone post
it here, please?

I’m not asking because I’m lazy to learn Ruby, I’m just lazy to learn how
Web servers work. :wink:

···


Phlip
http://www.greencheese.org/HoneySatellite
– /Hay sordos, pero no hay mas sordo que el que no quiere oir/ –

Phlip phlipcpp@yahoo.com writes:

Plenty of blogs report D. Thomas and crew immersed some of you and let you
write a Web server in under an hour.

Nobody has left a result of this experience on the 'net. Could someone post
it here, please?

We do this at our full-day Ruby tutorials, although we’ve never been
generous enough to give folks a full hour…:slight_smile: (and, yes, most folks get
something working in the time). However, I’m not sure anyone has ever
posted what they’ve written.

Dave

Plenty of blogs report D. Thomas and crew immersed some of you and let you
write a Web server in under an hour.

Nobody has left a result of this experience on the 'net. Could someone post
it here, please?

I’m not asking because I’m lazy to learn Ruby, I’m just lazy to learn how
Web servers work. :wink:

Have you seen:
http://www.xs4all.nl/~hipster/lib/ruby/httpd

The newer version:
http://www.xs4all.nl/~hipster/lib/ruby/httpd-1.6.1.6

also:
http://www.ruby-lang.org/en/raa-list.rhtml?id=542
http://www.ruby-lang.org/en/raa-list.rhtml?id=631
http://www.ruby-lang.org/en/raa-list.rhtml?id=54

regards,
-joe

Is it total immersion? Going from “WTH is Ruby?” to writing a web server
in under one hour is very impressive.

···

On Mon, Oct 28, 2002 at 09:41:08PM +0900, Dave Thomas wrote:

Phlip phlipcpp@yahoo.com writes:

Plenty of blogs report D. Thomas and crew immersed some of you and let you
write a Web server in under an hour.

Nobody has left a result of this experience on the 'net. Could someone post
it here, please?

We do this at our full-day Ruby tutorials, although we’ve never been
generous enough to give folks a full hour…:slight_smile: (and, yes, most folks get
something working in the time). However, I’m not sure anyone has ever
posted what they’ve written.


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

“You, sir, are nothing but a pathetically lame salesdroid!
I fart in your general direction!”
– Randseed on #Linux

Mauricio Fernández batsman.geo@yahoo.com writes:

We do this at our full-day Ruby tutorials, although we’ve never been
generous enough to give folks a full hour…:slight_smile: (and, yes, most folks get
something working in the time). However, I’m not sure anyone has ever
posted what they’ve written.

Is it total immersion? Going from “WTH is Ruby?” to writing a web server
in under one hour is very impressive.

It’s a six hour course, with lots of exercises. We normally ask people
to pair.

Dave

Dave Thomas wrote:

It’s a six hour course, with lots of exercises. We normally ask people
to pair.

Hi, Dave.

You of all people should have the snippet…

···


Phlip
greencheese.org
– Why is the “Cheesy Horror Movie Channel” called “SciFi”?? –

Rubies:

This would have taken me less than a wall-clock hour if I didn’t have a
life:

#!/usr/bin/ruby

a web server in Ruby

require ‘socket’

$mimeTypes = { ‘jpg’ => ‘image/jgp’, ‘gif’ => ‘image/gif’, ‘png’ =>
‘image/png’,
‘html’ => ‘text/html’, ‘pdf’ => ‘application/pdf’ }

$response = {} # TODO make me a map…

$response[200] =
’’'HTTP/1.0 200 Okay
Server: ws30
Content-type: %s

%s
’’’

$response[301] =
"""HTTP/1.0 301 Moved
Server: ws30
Content-type: text/plain
Location: %s

moved%s
"""

$response[404] =
’’'HTTP/1.0 404 Not Found
Server: ws30
Content-type: text/plain

%s not found%s
’’’

def serverSocket host, port

TODO make these real arguments…

s = TCPServer.new('localhost', port)
return s

end

def listen s
connection, client = s.accept()
return connection
end

def getRequest stream
method = nil

while 1 do
    line = stream.readline()
    if line.strip().length() == 0 then
        break
    elsif ! method
        method, uri, protocol = line.split()
    end
end

return uri

end

def listDirectory uri
return 'directory none of your business’
end

def getFile path
f = open( path )
return f.read() # TODO begin/rescue here
end

def getContent uri
print ‘fetching:’, uri

begin
    path = '.' + uri 
    if File.file?( path ) then
        return [ 200, getMime( uri ), getFile( path ) ]
    end
    if File.directory?( path ) then
        if( uri[uri.length() - 1].chr == '/' ) then
            return [ 200, 'text/html', listDirectory( uri ) ]
        else
            return [ 301, uri + '/' ]
        end
    else
        return [ 404, uri ]
    end

TODO actually stringify the error :wink:

rescue
    return [ 404, 'some dumb IO error' ]
end

end

def getMime uri
type = $mimeTypes[ uri.split(’.’)[-1]]
type = ‘text/plain’ if type == nil
return type
end

def sendResponse stream, content
$responseType = $response[content[0]]
content.push("")
response = sprintf($responseType, content[1], content[2] )
stream.write( response )
end

if FILE == $0 then

server = serverSocket( 'localhost', 8080 )

begin
    while 1 do
        stream = listen ( server )
        sendResponse( stream, getContent( getRequest( stream ) ) )
        stream.close()
    end
rescue
    print 'shutting down...'
end

server.close()

end

···


Phlip
http://flea.sourceforge.net
– Got in trouble at StarBucks. I tried to order
"A double latte mocha and a body piercing." –

Hi –

Rubies:

Horse and rider are one? :slight_smile:

def listen s
connection, client = s.accept()
return connection
end

I have a style-related question: I noticed that you put () after all
method names, and I was wondering what the origin/purpose/whatever of
that was. I’m neither trying to criticize it, nor likely to adopt
it myself :slight_smile: Just wondering.

David

···

On Tue, 29 Oct 2002, Phlip wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

I needed to use FTP using the Zaurus PDA. I can hardly believe how easy it
was to set up using Ruby.

The code follows if anyone else is interested.

require "net/ftp"
t = Net::FTP.new(host=nil,user=nil,passwd=nil)
t.connect(‘192.168.130.101’,port=4242)
t.login(user=‘root’, passwd=’ ‘)
files = t.chdir(’/mnt/card/Documents/application/octet-stream’)
print "Transferring Program"
t.puttextfile(“asz.py”,“asz.py”,callback=nil)
print "Transferring Index"
t.puttextfile(“asindex.pyz”,“asindex.pyz”,callback=nil)
print "Transferring Data"
t.puttextfile(“asksam.pyz”,“asksam.pyz”,callback=nil)
t.close

I do the same thing. It makes it clear that I’m calling a method and
not retrieving an attribute. I suppose it comes from my C++ background:

class Foo
{
void foo()
int bar;
};

Foo f;
f.foo();
int x = f.bar;

Paul

···

On Tue, Oct 29, 2002 at 11:38:57PM +0900, dblack@candle.superlink.net wrote:

I have a style-related question: I noticed that you put () after all
method names, and I was wondering what the origin/purpose/whatever of
that was. I’m neither trying to criticize it, nor likely to adopt
it myself :slight_smile: Just wondering.

dblack@candle.superlink.net wrote:

I have a style-related question: I noticed that you put () after all
method names, and I was wondering what the origin/purpose/whatever of
that was. I’m neither trying to criticize it, nor likely to adopt
it myself :slight_smile: Just wondering.

Hi David,

This is just my personal style. When I write network simulations (not
Ruby code fragments), I never put () for methods that are defined simply
using “attr_reader”, but other methods I usually put () to remind
me that I am “doing some real action” here. Well, in Ruby () is really
optional for methods without arguments, so I just take this advantage to
mimic the C’s member data access vs function call distinction. On the
other hand, for a method call with a single argument of type block, I
don’t put () either, because the {} is enough as a reminder to me that
“some real action is going on here”.

Regards,

Bill

Hi –

···

On Wed, 30 Oct 2002, Paul Brannan wrote:

On Tue, Oct 29, 2002 at 11:38:57PM +0900, dblack@candle.superlink.net wrote:

I have a style-related question: I noticed that you put () after all
method names, and I was wondering what the origin/purpose/whatever of
that was. I’m neither trying to criticize it, nor likely to adopt
it myself :slight_smile: Just wondering.

I do the same thing. It makes it clear that I’m calling a method and
not retrieving an attribute. I suppose it comes from my C++ background:

class Foo
{
void foo()
int bar;
};

Foo f;
f.foo();
int x = f.bar;

But since attributes are retrieved by method calls in Ruby, that
distinction doesn’t hold. Or, to put it another way, since all cases
of obj.message in Ruby are the foo() case, the () doesn’t actually add
any information or tell us anything. I guess that’s why it leapt off
the screen at me a bit.

David


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Hello William,

Tuesday, October 29, 2002, 7:11:34 PM, you wrote:

This is just my personal style. When I write network simulations (not
Ruby code fragments), I never put () for methods that are defined simply
using “attr_reader”, but other methods I usually put () to remind
me that I am “doing some real action” here.

i think real difference that you you want to highlight is between pure
functions and functions which have side-effect

···


Best regards,
Bulat mailto:bulatz@integ.ru

Hi –

···

On Wed, 30 Oct 2002, William Djaja Tjokroaminata wrote:

dblack@candle.superlink.net wrote:

I have a style-related question: I noticed that you put () after all
method names, and I was wondering what the origin/purpose/whatever of
that was. I’m neither trying to criticize it, nor likely to adopt
it myself :slight_smile: Just wondering.

Hi David,

This is just my personal style. When I write network simulations (not
Ruby code fragments), I never put () for methods that are defined simply
using “attr_reader”, but other methods I usually put () to remind
me that I am “doing some real action” here. Well, in Ruby () is really
optional for methods without arguments, so I just take this advantage to
mimic the C’s member data access vs function call distinction. On the
other hand, for a method call with a single argument of type block, I
don’t put () either, because the {} is enough as a reminder to me that
“some real action is going on here”.

Doesn’t that mean that you always have to know whether something was
defined with attr_reader? That seems like a kind of arbitrary thing
– it could always be redefined. Also, what if you’re using a library
package?

David


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Server)

I have a style-related question: I noticed that you put () after all
method names, and I was wondering what the origin/purpose/whatever of
that was. I’m neither trying to criticize it, nor likely to adopt
it myself :slight_smile: Just wondering.

I do the same thing. It makes it clear that I’m calling a method and
not retrieving an attribute. I suppose it comes from my C++ background:

That’s very interesting. I do the exact opposite
for the exact opposite reason. :slight_smile:

I.e., I don’t want the code to show whether I’m
calling a “regular” method or just an accessor.
This seems in line with Meyer’s Uniform Access
Principle, IIRC.

Hal

···

----- Original Message -----
From: “Paul Brannan” pbrannan@atdesk.com
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Tuesday, October 29, 2002 9:46 AM
Subject: Re: method-call style (was Re: Snippet: Tiny Featureless Ruby Web

On Tue, Oct 29, 2002 at 11:38:57PM +0900, dblack@candle.superlink.net wrote:

Paul Brannan wrote:

I do the same thing. It makes it clear that I’m calling a method and
not retrieving an attribute. I suppose it comes from my C++ background:

class Foo
{
void foo()
int bar;
};

Programming is about communicating with humans first, a computer second.

(I’m aware my snippet hardly exemplifies this lofty ideal…)

I do it to say “calling a function here”.

Props to Matz for not making me always do it. For example,

    puts indescribable.public_methods.sort()

Drop the middle () because it’s redundant.

And where would http://flea.sf.net without the call chain?

root.move.move.move.move.move.color(White).longer(2).
push.link(ax).pop.right.
push.link(ax).pop.right.
push.link(ax).pop.right.
push.link(ax).pop.right.
push.link(ax).pop.right.
push.link(ax).pop.right

Those are procedural function calls, but I want them to look like commands
in a miniature declarative language. And the ones that need arguments get
() for parsinomy.

···


Phlip
greencheese.org
– Wanted: Marriage counselor who also keeps pet rats –

In Ruby, attributes are method calls. However, they are a special type
of method call. Attributes are guaranteed to never modify the object.
And if the object isn’t modified, then the attribute should remain the
same. I think the distinction is supported by the semantics of
attributes, if not by the language itself.

Paul

···

On Wed, Oct 30, 2002 at 01:11:43AM +0900, dblack@candle.superlink.net wrote:

But since attributes are retrieved by method calls in Ruby, that
distinction doesn’t hold. Or, to put it another way, since all cases
of obj.message in Ruby are the foo() case, the () doesn’t actually add
any information or tell us anything. I guess that’s why it leapt off
the screen at me a bit.

Hi –

···

On Thu, 31 Oct 2002, Phlip wrote:

Paul Brannan wrote:

I do the same thing. It makes it clear that I’m calling a method and
not retrieving an attribute. I suppose it comes from my C++ background:

class Foo
{
void foo()
int bar;
};

Programming is about communicating with humans first, a computer second.

(I’m aware my snippet hardly exemplifies this lofty ideal…)

I do it to say “calling a function here”.

Props to Matz for not making me always do it. For example,

    puts indescribable.public_methods.sort()

Drop the middle () because it’s redundant.

True… but the last () is too, since public_methods.sort can only be
a method call. I guess it’s a question of what the eye is used to.
As you point out, we all get to choose, without any loss of clarity
:slight_smile:

David


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Hi Bulat,

Yes, I agree with you; I think you have made it clearer, similar to Paul’s
post.

Regards,

Bill

···

Bulat Ziganshin bulatz@integ.ru wrote:

This is just my personal style. When I write network simulations (not
Ruby code fragments), I never put () for methods that are defined simply
using “attr_reader”, but other methods I usually put () to remind
me that I am “doing some real action” here.

i think real difference that you you want to highlight is between pure
functions and functions which have side-effect

dblack@candle.superlink.net wrote:

Doesn’t that mean that you always have to know whether something was
defined with attr_reader? That seems like a kind of arbitrary thing
– it could always be redefined. Also, what if you’re using a library
package?

Hi David,

I think you have a very good point here.

In my case, in some sense I develop the object model hierarchy from
scratch, so I do know all the properties of the simulation objects. For
other people, in my manual for each class I distinguish between
“attributes” and “methods”. Attributes are things that are implemented
using the “@var”. This is done so that people who want to inherit from
a class can access the “@var” directly and do not have to use
“self.var”. Well, now people who know OO well may tell me whether it is
better for a derived class to access the “@var” directly or instead to use
“self.var”.

If I’m using a library package, on the other hand, then it will be really
subjective. For example, I may write array.length but array.sort(). It
is just a personal habit to treat “length” as if it is some data stored in
memory but “sort” as resulting in some processing. Well, as already
pointed out by someone else, Meyer’s uniform access principle says that we
don’t need to know how “length” is really implemented; so this is really
just a personal style.

Regards,

Bill