ALGOBIT

2011/05/06

TCPサーバ ruby と python

Filed under: 離散的な気まぐれ — タグ: , , , — Kohyama @ 11:01

自分用まとめです.
各言語の TCPサーバ雛形としてのエコーサーバ.
クライアントから来たメッセージが変数で見える最小コードシリーズ.

ruby 版.
ポートを変えてる以外は 本家のリファレンス そのままですが.

require 'socket'

gs = TCPServer.open(1111)
addr = gs.addr
addr.shift

while true
    Thread.start(gs.accept) do |cs|
        while cs.gets
            cs.write($_)
        end
        cs.close
    end
end

python 版.
抽象化レイヤーは他にもあるようですが, 複数クライアントを相手にする, クライアントから送られて来たデータが変数で見える, 最小コードという趣旨だと SocketServer.ThreadingTCPServer が一番簡単なようです.

import SocketServer

class MyHandler(SocketServer.BaseRequestHandler):
	def handle(self):
		while True:
			data = self.request.recv(1024)
			if len(data) == 0:
				self.request.close()
				return
			self.request.send(data)

if __name__ == "__main__":
	HOST, PORT = "localhost", 1111
	server = SocketServer.ThreadingTCPServer((HOST, PORT), MyHandler)
	server.serve_forever()

UNIX系なら, いつも通りそれぞれ「#!/usr/bin/env ruby」, 「#!/usr/bin/env python」を一行目に挿入して chmod +x で直接実行.

2010/10/08

ハノイとバベルの塔 第八階 – 端末アニメ in Ruby

Filed under: 離散的な気まぐれ — タグ: , — Kohyama @ 02:53

第五回, 第六回 と同様の構造で書いてみます.

#!/usr/bin/ruby

def move(src, tmp, dst, n)
	if (n == 0)
		return
	end
	move(src, dst, tmp, n - 1)
	dst.push(src.pop())
	printAStep()
	move(tmp, src, dst, n - 1)
end

def printAStep()
	sleep($w/1000.0)
	print "\x1b[2J\x1b[2;1H"
	$N.times do |i|
		$pegs.each do |peg|
			if (peg.length < $N - i)
				print " " + $ws + "|" + $ws + " "
			else
				l = peg[$N - i - 1]
				print " " + $ws[l..-1] + $bar[0..(l - 1)] + "|" +
					$bar[0..(l - 1)] + $ws[l..-1] + " "
			end
		end
		print "\n"
	end
	print $grnd + "\n"
end

$N = (0 < ARGV.length) ? ARGV[0].to_i : 3
$w = (1 < ARGV.length) ? ARGV[1].to_i : 500
$pegs = [[],[],[]]
$N.downto(1) do |i|
	$pegs[0].push(i)
end

$ws = " "*$N
$bar = "-"*$N
$grnd = "="*(6*$N + 9)

printAStep()
move($pegs[0], $pegs[1], $pegs[2], $N)

$N.times do |i| ... end のループに, 数値もオブジェクトであることや, ブロック(無名関数)を受け取る既定義メソッドなどに言語の特色が出ています.

手続き中で任意個の '-' からなる文字列を生成してもさほど遅くはならないと思うのですが, 言語毎の特色を見るために「$N個の '-' からなる文字列を作っておいて, 部分文字列を使う」ように書いています.

n個の '-' からなる文字列を "-"*n と書けるのは
* という演算子の機能を規定する言語の組み込み機能ではありません.
* も単なるメソッドであり, "-"*n の実態は "-".*(n) すなわち, 文字列 "-" のインスタンスメソッド * を引数 n で呼び出しているだけであり, クラスに適切なメソッドを定義することで実現されています.

部分文字列を取り出すときに, 配列の添字に負数が利用できるのも良いですね.

第五回, 第六回 で利用した「ランダムアクセスできるスタック」みたいな能力を「配列」が持っていることで記述量はずいぶん減っています.


Yugui
オライリージャパン
発売日:2008-06-26

本書は対象読者の設定が明快です.
既にいくつかのプログラミング言語を実用していて, 他のプログラミング言語と Ruby が違うところだけ知りたい人向けです.
従ってページ数に対して情報量が多く感じました. お買い得.
多くの言語を操る著者さんの, 特定のプログラミング言語に偏った考え方や用語にならないようにという配慮が素敵です.

Copyright © 2010 Yoshinori Kohyama All Rights Reserved.