| 著作一覧 |
.... Finished in 164.096424 seconds. 1) Failure: test_verify(OpenSSL::TestX509Store) [./openssl/test_x509store.rb:163]: <true> expected but was <false>. 970 tests, 10357 assertions, 1 failures, 0 errors ~/devl/ruby-1.8.2/test$ ruby -v ruby 1.8.2 (2004-12-25) [powerpc-darwin7.7.0]
opensslがなんであるか知る気も起こさないようにしてきたけどそろそろ知るべき時が来たような気がする。
#とりあえず、Macでrjb-0.1.7のtest.rbは通るな。
言語に対して、文法表現と、それを利用して文を解釈するインタプリタを一緒に定義する
確かになんだかわからん。
ミソは終端表現と非終端表現を一緒に扱えるようにするという点なのかな。
という記事を思い出したので調査。というか、インタープリタは結構使うからだが(エンジンを借りる場合もあればでっち上げる場合もある)。
Four patterns were voted off. Factory Method (due to the confusion over what it means - the pattern is different to the more common usage of the term), Bridge, Flyweight, and Interpreter.
この議論はどういう観点からなんだろうか(ファクトリメソッドパターンは名前が悪いという理由が書かれているが)? すでに言語あるいはミドルウェアで標準的に提供されている/考慮不要化されているために、デザインパターンとしての存在意義を失ったということなのかな?
Javaでフライウェイトを利用するのは参照されているかどうかを判断できないのですごく難しいが、そういう意味なのかな?
例)たくさんのレコードの繰り返しにフライウェイトを使いたい場合
RecordObject flyweight = null;
while (resultSet.next()) {
// 例えばCOMであれば、
// if (flyweight == null) {
// flyweight = new RecordObject();
// }
// if (flyweight.refCount() > 1) {
// flyweight = new RecordObject(); // しょうがないな
// }
// と参照カウンタが1(生成時のデフォルト)であればそのまま同じインスタンスを利用できる
flyweight = new RecordObject(); // フライウェイトじゃないじゃん
// Javaだとconsumerが(たとえばCollectionに入れるなどで)参照を保持したかどうかは判断できないので常に作り直しが必要となる。
// これを防ぐにはResultSetやRowSetのように同一インスタンス内に次のレコードの内容をフィルする方法を取る必要がある。
flyweight.fill(resultSet);
consumer.nextRecord(flyweight);
}
デザインパターンのインタープリタパターンってこんな感じになるのかな(と、出先なものでGoFに当たれないのがなんとも。というか自分のためのメモですね)。
=begin
以下のプログラムのインタープリタを仮定する。
a = 0
loop:
a = a + 1
if a < 5
goto loop
end
puts a
=end
class Var
def initialize(name)
@name = name
end
def interpret(c)
c[@name]
end
attr_reader :name
end
class Let
def initialize(lval, rval)
@lval = lval
@rval = rval
end
def interpret(c)
c[@lval.name] = @rval.interpret(c)
end
end
class Add
def initialize(lval, rval)
@lval = lval #これ名前が悪いな
@rval = rval
end
def interpret(c)
@lval.interpret(c) + @rval.interpret(c)
end
end
class Lt
def initialize(lval, rval)
@lval = lval #同じく悪い名前
@rval = rval
end
def interpret(c)
@lval.interpret(c) < @rval.interpret(c)
end
end
class Num
def initialize(val)
@value = val
end
def interpret(c)
@value
end
end
class Label
def initialize(name, index)
@name = name
@index = index
end
def interpret(c)
nil
end
attr_reader :index, :name
end
class If
def initialize(cond, clause)
@cond = cond
@clause = clause
end
def interpret(c)
if @cond.interpret(c)
@clause.interpret(c)
end
end
end
class Goto
def initialize(label)
@label = label
end
def interpret(c)
c.next = @label.index
end
end
class Puts
def initialize(var)
@var = var
end
def interpret(c)
puts @var.interpret(c)
end
end
class Context
def initialize()
@pgm = []
@var = {}
@next = 0
end
def interpret()
while @next < @pgm.size
n = @next
@next += 1
@pgm[n].interpret(self)
end
end
def add(nd)
@pgm << nd
end
def []=(n, v)
@var[n] = v
end
def [](n)
@var[n]
end
def current
@pgm.size
end
def label(name)
@pgm.each do |x|
return x if Label === x and x.name == name
end
nil
end
attr_accessor :next
end
c = Context.new()
c.add(Let.new(Var.new('a'), Num.new(0)))
c.add(Label.new('loop', c.current))
c.add(Let.new(Var.new('a'), Add.new(Var.new('a'), Num.new(1))))
c.add(If.new(Lt.new(Var.new('a'), Num.new(5)), Goto.new(c.label('loop'))))
c.add(Puts.new(Var.new('a')))
c.interpret
ジェズイットを見習え |