Extend Html4?

Suppose I have this code:

$cgi = CGI.new(‘html4’)
puts $cgi.p{“Hello, “+$cgi.b{“world”}+”!”}

Hello, world!

How can I become able to write it like this?

puts p{“Hello, “+b{“world”}+”!”}

I want the “p”, “b” etc. methods to be exported to my namespace. They
are defined inside Html4:

class CGI

module Html4

end
end

I can’t just type “extend Html4” because Html4 is defined inside the
CGI class.

Here’s what I did, although it may not suit your tastes:

class MyCGI < CGI
def hello_world
return p{"Hello, " + b{“world”} + “!”}
end
end

c = MyCGI.new(“html4”)
puts c.hello_world

This way I can keep all the messages in my subclass, where they are fairly
self-contained. This way, if I ever need to switch from CGI to XML or
plain output for the screen, instead of rewriting my main module, I just
have to make a MyXML or MyMessages class and use it in my main script
instead.

I also build methods to translate CGI stuff like parameters into what my
main script needs to know. Prevents my main script from having to know
that the request started life as CGI.

Not that I ever expect to do need to switch from CGI to something else, but
the main benefit is that it keeps program logic separate from message
output logic, so both the program and output code is easier to follow…
and it makes writing the HTML methods a lot easier.

-michael

···

On Saturday 10 August 2002 18:44, Philip Mak wrote:

How can I become able to write it like this?

puts p{“Hello, “+b{“world”}+”!”}

I want the “p”, “b” etc. methods to be exported to my namespace. They
are defined inside Html4:

++++++++++++++++++++++++++++++++++++++++++
Michael C. Libby x@ichimunki.com
public key: http://www.ichimunki.com/public_key.txt
web site: http://www.ichimunki.com
++++++++++++++++++++++++++++++++++++++++++

Hello –

Suppose I have this code:

$cgi = CGI.new(‘html4’)
puts $cgi.p{“Hello, “+$cgi.b{“world”}+”!”}

Hello, world!

How can I become able to write it like this?

puts p{“Hello, “+b{“world”}+”!”}

I want the “p”, “b” etc. methods to be exported to my namespace. They
are defined inside Html4:

class CGI

module Html4

end
end

I can’t just type “extend Html4” because Html4 is defined inside the
CGI class.

You can include the module, but keep reading below…

require 'cgi’
include CGI::Html3
cgi = CGI.new(“html3”)
puts html { h1 { “hi” } }

For reasons I haven’t fully looked into, this doesn’t print the
DOCTYPE declaration; it just prints:

hi

so it’s probably treading where it shouldn’t. But maybe it could
point you in the right direction (if there is one :slight_smile:

David

···

On Sun, 11 Aug 2002, Philip Mak wrote:


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

You can include the module, but keep reading below…

require 'cgi’
include CGI::Html3
cgi = CGI.new(“html3”)
puts html { h1 { “hi” } }

Hmm, it’s a little weird that the html, h1, etc. methods won’t work
until CGI.new has been called.

Is it considered bad programming practice to make use of a module
that’s defined inside someone else’s class?

For reasons I haven’t fully looked into, this doesn’t print the
DOCTYPE declaration; it just prints:

hi

so it’s probably treading where it shouldn’t. But maybe it could
point you in the right direction (if there is one :slight_smile:

I’m guessing it’s because when you call “html” instead of “cgi.html”,
it fails to find something on self that would be present if self was a
true CGI object.

···

On Sun, Aug 11, 2002 at 09:16:01AM +0900, dblack@candle.superlink.net wrote:

Hi –

···

On Sun, 11 Aug 2002, Philip Mak wrote:

On Sun, Aug 11, 2002 at 09:16:01AM +0900, dblack@candle.superlink.net wrote:

You can include the module, but keep reading below…

require 'cgi’
include CGI::Html3
cgi = CGI.new(“html3”)
puts html { h1 { “hi” } }

Hmm, it’s a little weird that the html, h1, etc. methods won’t work
until CGI.new has been called.

That’s because cgi.rb does a bunch of dynamic creation of methods.
(Look at #element_init, of which there’s one in each of the Html*
modules.) So those methods don’t actually exist until the CGI object
is created.

David


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

That’s because cgi.rb does a bunch of dynamic creation of methods.
(Look at #element_init, of which there’s one in each of the Html*
modules.) So those methods don’t actually exist until the CGI object
is created.

Isn’t that just a design issue, though? Since Ruby is a totally dynamic
language, anything that is fundamental to the use of the module could simply
be coded at module-level, and set module-level variables that object
instances and module methods use.

Mind you, maybe this isn’t possible with modules. I do it a lot with classes,
but haven’t tried it with a module.

Hi –

···

On Sun, 11 Aug 2002, Harry Ohlsen wrote:

That’s because cgi.rb does a bunch of dynamic creation of methods.
(Look at #element_init, of which there’s one in each of the Html*
modules.) So those methods don’t actually exist until the CGI object
is created.

Isn’t that just a design issue, though? Since Ruby is a totally dynamic
language, anything that is fundamental to the use of the module could simply
be coded at module-level, and set module-level variables that object
instances and module methods use.

Mind you, maybe this isn’t possible with modules. I do it a lot with
classes, but haven’t tried it with a module.

I’m not quite following. Do you mean this specifically in relation
to the design of cgi.rb?

David


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

I’m not quite following. Do you mean this specifically in relation
to the design of cgi.rb?

Sorry, I should have been clearer. The original issue that was mentioned
(assuming I didn’t come into the thread too late) was that if one does
something like:

require 'cgi’
include CGI::Html3

this makes the module-level method available without specying the “namespace”,
so that you can do things like:

puts html { h1 { “Hello, world!” } }

but that then the DOCTYPE specification doesn’t end up in the output.
Instead, one sees something like

Hello, world!

I thought people were saying the reason for this was that the DOCTYPE stuff
only happens if one constructs a new CGI instance in the code.

What I meant was that if the construction of that object has the side-effect
of setting up some infrastructure, then that infrastructure could,
potentially be set up as top-level code.

As I say, I’ve never tried this in a module, but have done it in classes quite
a few times. For example, …

class Fred
@@REPOSITORY = “Fred.saved”

  @@freds = []

  if FileTest.exists? @@REPOSITORY
     File.open(@@REPOSITORY) do |file|
        @@freds = Marshal.load(file.readlines)
     end
  end

  def initialize
     # ...
  end

  # ...

end

Ie, by doing this stuff at the class level, it happens automagically, making
it transparent to the user of the class.

I’m just suggesting that perhaps this is something the CGI library could be
doing, if the setup of the DOCTYPE is something that is always wanted.

Maybe I’ve completely missed the point of the discussion, though … not
unprecedented :-).

Hi –

I’m not quite following. Do you mean this specifically in relation
to the design of cgi.rb?

Sorry, I should have been clearer. The original issue that was mentioned
(assuming I didn’t come into the thread too late) was that if one does
something like:

require 'cgi’
include CGI::Html3

this makes the module-level method available without specying the “namespace”,
so that you can do things like:

puts html { h1 { “Hello, world!” } }

but that then the DOCTYPE specification doesn’t end up in the output.
Instead, one sees something like

Hello, world!

I thought people were saying the reason for this was that the DOCTYPE stuff
only happens if one constructs a new CGI instance in the code.

What I meant was that if the construction of that object has the side-effect
of setting up some infrastructure, then that infrastructure could,
potentially be set up as top-level code.

That is what we were talking about, but it’s all based on trying to do
an end pass around the official API, so it’s not something that I
would really recommend being changed in cgi.rb :slight_smile:

By the way, I did figure out why the DOCTYPE declaration doesn’t
appear: the factory-created #html method in a normal CGI object
actually gets overridden by an “extend HtmlExtension”. And, sure
enough, if you do:

require './cgi.rb’
cgi = CGI.new(“html4”)
include CGI::Html4, CGI::HtmlExtension
puts html { }

it does output the whole thing. But until we hear otherwise, I would
assume this is all not guaranteed, as it’s probing into the inner
workings of the extension. (But quite interesting, isn’t it? :slight_smile:

David

···

On Sun, 11 Aug 2002, Harry Ohlsen wrote:


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