From: gotoken@... (GOTO Kentaro) Date: 1999-07-17T17:42:16+09:00 Subject: [ruby-talk:00503] FromJapan: #3 Hi folks! In past four weeks, about 550 messages are posted to ruby-list . 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 (__;;;;;;;;;;;;