[ruby-talk:00503] FromJapan: #3
From:
gotoken@... (GOTO Kentaro)
Date:
1999-07-17 08:42:16 UTC
List:
ruby-talk #503
Hi folks!
In past four weeks, about 550 messages are posted to ruby-list <dizzy>.
I was so busy and didn't follow almost all of them.... So, I've decide to
split into several issues. I also entrust the pick-up job to ruby.freak.ne.jp
which is a famous unofficial portal site for Ruby (in Japanese).
Today, I pick up 11 topics:
Contrib
[ruby-list:14843] Ruby/Tk TkText#dump
[ruby-list:14960] http-access-0.0.2 managing HTTP/1.0 & HTTP/1.1
[ruby-list:15042] Ruby package for Debian GNU/Linux
[ruby-list:15056] mod_ruby-0.1.3 for Apache
Q and A
[ruby-list:14908] a method which is always called when GC?
[ruby-list:14970] thread with curses
Tips
[ruby-list:14916] HEAD requesting to a `Keep-Alive' HTTP server.
[ruby-list:14972] embedding documet rd
[ruby-list:15009] Re: detecting failure of str.to_i, str.to_f
Fringe
[ruby-list:14890] Object-Oriented Software Construction (2nd edition)
[ruby-list:15064] `Hako iri Musume' in Ruby/TK
======================================================================
Contrib [ftp://ftp.netlab.co.jp/pub/lang/ruby/contrib/]
______________________________________________________________________
[ruby-list:14843] Ruby/Tk TkText#dump
Tomoyuki KOSHIMIZU wrote TkText#dump which corresponds to `text dump'
of Tcl/Tk. This code has already been included in the released version.
______________________________________________________________________
[ruby-list:14960] http-access-0.0.2 managing HTTP/1.0 & HTTP/1.1
Takahiro MAEBASHI put http-access-0.0.2. It is result of Nahi's
patch and TAKAHASHI Masayoshi's patch for url-parse.rb.
This version supports
- port number scheme of url
- HTTP/1.0
- responses from servers which use LF-only for HTTP header delimiter
______________________________________________________________________
[ruby-list:15042] Ruby package for Debian GNU/Linux
Good new for a Debian GNU/Linux user!
Debian's official site http://www.debian.org/ started distribing
Ruby package.
______________________________________________________________________
[ruby-list:15056] mod_ruby-0.1.3 for Apache
Shugo MAEDA put mod_ruby-0.1.3. Minor change only.
He also seeks someone who uses mod_ruby on RedHat.
======================================================================
Q and A
______________________________________________________________________
[ruby-list:14908] a method which is always called when GC?
Question:
How can I define FOO#bye such that is always called
when each object of FOO would be GC?
For example, does the following work?
class FOO
require "final"
def initialize(filename)
@x = filename
ObjectSpace.define_finalizer(self, lambda{bye})
end
def bye
raise "gone" unless @x
open(@x, "a+"){|f| f << $$ << ": bye\n"}
@x = nil
end
end
Answer:
No, it doesn't. If a proc which is generated in method's
context is passed to a finalizer, a reference from finalizer
to self is made. It is because of such object shall never
be garbage.
See Akira YAMADA's `tempfile.rb' for use of the finalizer.
In tempfile.rb, He devised as follows:
* creating proc by a class method to avoid to refer self
* giving needed information as options
Essentialy, GC and finalizer are ill-matched each other (why
did Java adopt?). So, the finalizer is made inconvenient on
purpose. Maybe, Java-like finalizer will be adopted in future
but it's difficult to be efficient.
______________________________________________________________________
[ruby-list:14970] thread with curses
Question:
I'm trying to make code like `talk' which has two windows
in a terminal: one of them is used to input and another to
output by server. But `getstr' is called for input then
the program stop...
Answer:
Well, curses is not thread safe. I guess to check by IO:select
and to input by getch as follows:
require "curses"
include Curses
module Curses
class Window
def get_str
str = ""
max = str.length
line = cury
col = curx
catch(:CURSES_WINDOW_GET_STR) do
loop do
setpos(line, col)
addstr(" " * max)
setpos(line, col)
addstr(str)
refresh
sleep(0.1) if (IO::select([ STDIN ]))
case (c = getch)
when ?\C-h
str.chop!
when ?\C-u
str = ""
when ?\n
throw(:CURSES_WINDOW_GET_STR,
unless (str.empty?) then str end)
when ?\C-g
throw(:CURSES_WINDOW_GET_STR, nil)
else
str << c.chr
end
max = [ max, str.length ].max
end
end
end
end
end
init_screen
cbreak
noecho
max = lines - 3
output = Window.new( max, cols, 0, 0)
output.setpos( 0, 0)
input = Window.new( 2, cols, max + 1, 0)
Thread.start do
i = 0
while i < 100
output.addstr( i.to_s + "\n")
output.refresh
sleep 1
i += 1
end
end
while TRUE
input.setpos( 1, 0)
input.addstr( "input > ")
input.refresh
# sleep 2
tmp = input.get_str
if tmp == "q"
break
end
output.addstr( tmp + "\n")
output.refresh
input.clear
end
input.close
output.close
close_screen
======================================================================
Tips
______________________________________________________________________
[ruby-list:14916] HEAD requesting to a `Keep-Alive' HTTP server.
On HTTP. If an agent sents some requests in a time to a server,
using Keep-Alive is a smart solution. But some servers don't support
Keep-Alive. And furthermore, a agent cannot know whether the server
supports that or not, until getting server's response.
The following solves such difficulty. The point is to check both
`Status' and `Connection'. (Suggested by Wakou AOYAMA who also
wrote telnet.rb)
#!/usr/local/bin/ruby
require "socket"
CR = "\015"
LF = "\012"
EOL = CR + LF
def get_head(host, port, files)
heads = {}
sock = nil
for i in 0 ... files.size
if sock == nil or sock.closed?
sock = TCPsocket.open(host, port)
sock.binmode
STDERR.print "server open.\n"
end
if i == files.size - 1
connection = "Close"
else
connection = "Keep-Alive"
end
sock << "HEAD " << files[i] << " HTTP/1.1" << EOL
sock << "Host: " << host << EOL
sock << "Connection: " << connection << EOL
sock << EOL
status = sock.gets(LF)
if CR == status[status.size - 2].chr
eol = EOL
else
eol = LF
end
head = sock.gets(eol + eol)
if (/Connection:\s+Close/ni === head) or
((/HTTP\/1\.0/ni === status) and
(not /Connection:\s+Keep-Alive/ni === head))
sock.close if not sock.closed?
end
heads[files[i]] = head
end
sock.close if not sock.closed?
heads
end
port = "80"
host = "www.jin.gr.jp"
files = %w[ /~nahi/ /~nahi/Ruby/ /~nahi/link-Ruby.html ]
### Keep-Alive unavailable host:
#host = "www.isc.meiji.ac.jp"
#files = %w[ /~ee77038/ /~ee77038/ruby/index.html /~ee77038/ruby/program.htm ]
### HTTP 1.0 only host:
#host = "www2c.biglobe.ne.jp"
#files = %w[ / /~hosoda/ ]
get_head(host, port, files).each do |file, head|
print file, "\n"
print head
end
______________________________________________________________________
[ruby-list:14972] embedding documet rd
There is POD (plain old document) which is a comment style in
Perl to generate online manual from the code by perl2man.
(See also perlpod(1)). Ruby has similar feature RD (ruby document).
Only ftp://ftp.netlab.co.jp/pub/lang/ruby/contrib/rd2html is known
as a tool to convert from this format. One can obtain the document of
CGI.rb by rd2html.
RD features have been released in [ruby-dev:3045]. Matz said that
the manuscript of the first book about Ruby is described in this
format.
Heading
= Chapter
== Section
=== Subsection
+ Chapter without numbering
++ Section without numbering
+++ Subsection without numbering
Listing
* Let's list
* like this.
* indent level
* is supported
Enumerating
(1) Let's list
(2) like this.
(1) renumbering
Definition
: bar
came from fubar (See `fubar')
: foo
came from fubar (See `fubar')
: fubar
(US Army) acronym of `fucked up beyond all repaired'
Verbatim
str = "TAB indented lines are regarded as code. "
# sorry for difficulty to see
Footnote
RD is designed for a book. (-- coming soon in Japan! --)
Terminology
[-- class --] will be appeared in glossary.
______________________________________________________________________
[ruby-list:15009] Re: detecting failure of str.to_i, str.to_f
String#to_i/to_f converts string into a numeic within the receiver
string can be regarded as an expression of numeric. But sometime
one wants to detect whether whole of string is numric or not.
For example
"12.3abc".to_i #=> 12
"12.3abc".to_f #=> 12.3
whareas "12.3abc" itself is not an expression of any numeric.
(WATANABE Tetsuya pointed out that this spec from atoi() then Perl)
ARIMA Yasuhiro wrote to_int/to_float which converts but raises error
if the receiver string is not pure numeric exp. "It's not completed",
he comments, "but enough to my current problem". Indeed, this regexp
is not support freely appearance of `_' in the numeric literal.
class String
def to_float
return to_f if self =~ /^[-+]?((\d+)?(\.\d+))|((\d+)(\.\d+)?)([eE][-+]\d+)?$/
raise "fail at convert string to float"
end
def to_int
return to_i if self =~ /^[-+]?(\d+)$/
raise "fail at convert string to int"
end
end
if __FILE__ == $0
def c x
begin
x.to_s.to_float
begin
x.to_s.to_int
t = "int"
rescue
t = "float"
end
rescue
t = "string"
end
end
def checkall ar
ar.each do |x|
t = c(x)
print t, " ", x, "\n"
end
end
ar = []
ar << "abc"
ar << "123"
ar << "1.23"
ar << "1.23e+4"
ar << ".123"
ar << "1e2"
checkall ar
end
======================================================================
Fringe
______________________________________________________________________
[ruby-list:14890] Object-Oriented Software Construction (2nd edition)
Akira ENDO (aka FAQ editor) might do double-click; He has received
two same books from amazon.com.
# By the way, one of Gotoken's friends received three same books from
# amazon.com, one day. He might do triple-click. Be careful :-)
The book is Bertrand Meyer's `Object-Oriented Software Construction
(2nd edition)'. Akira called somebody who wants that book and lives
near his hometown. Mokoto asked how good the book is (but he lives
in Massachusetts). Yoshifumi and Matz have good word for the
1st edition of this book. Indeed, Matz sometimes confesses that he
was given a shock by this book about ten years ago. He also give
a proviso that Eiffel is not `the main current' nor `a orthodox' of
OOPL. Of course, the value of Mayer's book is not change. It's great.
I think so. But 2nd ed. is too thick, about 1200 pages!
______________________________________________________________________
[ruby-list:15064] Hako iri Musume in Ruby/TK
Masatoshi SEKI makes us merry by his implementation of a traditional
Japanese toy `Hako iri Musume'. I should explain what that is.
`Hako iri Musume' means `daughter(Musume) in(iri) a box(Hako)'.
In ancient Japan (and now?), a daughter is cherished very very much.
It was not easy to out for her because her family hampted (they might
worry she would be abducted?). So, such a chetished girl is expressed
figuratively `Hako iri Musume'. The subject of this game is to help
a marchant's daughter out.
The goal is take her (the biggest piece) to the opposite position
(see below). Enjoy! # No fanfare will be played when you succeed.
+------+-------------+------+ +---------------------------+
| | | | | ? |
| | | | | ? |
|Father| Daughter |Mother| | ? |
| | | | | ? ? |
| | | | | ? |
+------+------+------+------+ | ? |
| | | | | | ? |
| boy | boy | boy | boy | ===> | ? |
+------+------+------+------+ | +-------------+ ? |
| | | | | | | |
| | manager | | | | | |
|serv- +-------------+serv- | | ? | Daughter | |
| ant| | ant| | | | |
| | | | | | | |
+------+-------------+------+ +------+-------------+------+
# I (gotoken) replaced Japanese characters by ASCII characters.
require 'tk'
class House
def initialize(parent=nil, unit=32)
@w = 4
@h = 5
@unit_size = unit
@widget = TkFrame.new(parent,
'width' => @unit_size * @w,
'height' => @unit_size * @h).pack
@chips = []
end
attr :widget
attr :unit_size
attr :chips
def enter(chip)
@chips.push chip
end
def wall
hash = {}
(-1..@w).each do |i|
hash[[i, -1]] = true
hash[[i, @h]] = true
end
(-1..@h).each do |i|
hash[[-1, i]] = true
hash[[@w, i]] = true
end
hash
end
def move?(chip, dx, dy)
field = self.wall
@chips.each do |c|
unless c == chip
c.area.each do |a|
field[a] = chip
end
end
end
chip.area(dx, dy).each do |a|
return false if field[a]
end
return true
end
end
$house = house = House.new(nil, 64)
class Chip
def initialize(house, name, x, y, w=1, h=1)
@name = name
@w = w
@h = h
@widget = TkLabel.new(house.widget,
'text' => name,
'relief' => 'raised')
@house = house
@unit = @house.unit_size
moveto(x, y)
@house = house.enter(self)
@widget.bind('1', proc{|e| do_press e.x, e.y})
@widget.bind('B1-Motion', proc{|x, y| do_motion x, y}, "%x %y")
@widget.bind('ButtonRelease-1',
proc{|x, y| do_release x, y}, "%x %y")
end
attr :name
def area(dx=0, dy=0)
v = []
for i in (1..@h)
for j in (1..@w)
v.push([dx + @x + j - 1, dy + @y + i - 1])
end
end
v
end
def moveto(x, y)
@x = x
@y = y
@widget.place('x' => @unit * x,
'y' => @unit * y,
'width' => @unit * @w,
'height' => @unit * @h)
end
def move(dx, dy)
x = @x + dx
y = @y + dy
moveto(x, y)
end
def do_press(x, y)
end
def do_motion(x, y)
if x >= @unit * @w
dx = 1
elsif x < 0
dx = -1
else
dx = 0
end
if y >= @unit * @h
dy = 1
elsif y < 0
dy = -1
else
dy = 0
end
if (dx != 0)
dy = 0
end
return if (dx == 0) and (dy == 0)
try_move(dx, dy)
end
def do_release(x, y)
end
def try_move(dx, dy)
if $house.move?(self, dx, dy)
move(dx, dy)
end
end
end
she = Chip.new(house, 'Daughter', 1, 0, 2, 2)
father = Chip.new(house, "Father", 0, 0, 1, 2)
mother = Chip.new(house, "Mother", 3, 0, 1, 2)
kozou = []
(0..3).each do |i|
kozou.push Chip.new(house, "boy", i, 2)
end
genan = []
(0..1).each do |i|
genan.push Chip.new(house, "servant", i * 3, 3, 1, 2)
end
bantou = Chip.new(house, "manager", 1, 3, 2, 1)
Tk.mainloop
======================================================================
-- gotoken
PS
I wached Star Wars Episode I. I was very surprised because Jedi knights
often did OZIGI (__). They must be samurai. Sith? they are ninja.
By the way, (__) stands for a downcasting face: underscores for closed eyes.
We use also (__;; in Japan. This face is covered (cold) sweats and means
that she is expressing apology with all her might.
e.g. My apology for long suspend of FromJapan (__;;;;;;;;;;;;