なひです。

どなたかruby mappingに関する相談に乗ってください。以下ではXML Schemaによ
る型定義とRubyの言語マッピングを例にしていますが、本質的には「enumの言語
マッピングをどうしよう」なので、RELAXでもCORBA IDLでもASN.1でもあてはま
ると思います。

以下のようなXML Schemaによる定義があるとします。

<?xml version="1.0"?>
<schema
    xmlns="http://www.w3.org/2001/XMLSchema"
    xmlns:txd="urn:org.example.enumsample"
    targetNamespace="urn:org.example.enumsample">

  <complexType name="hobbit">
    <sequence>
      <element name="name" type="txd:hobbitname"/>
      <element name="age" type="xsd:int"/>
    </sequence>
  </complexType>

  <simpleType name="hobbitname">
    <restriction base="xsd:string">
      <enumeration value="frodo"/>
      <enumeration value="sam"/>
      <enumeration value="meriadoc"/>
      <enumeration value="peregrin"/>
    </restriction>
  </simpleType>
</schema>

構造体っぽいhobbitと、その名前をいくつかに制限するためのenumである
hobbitnameという型が定義されています。現在、soap4r/CVSを使うと、以下のよ
うに、hobbitのほうだけのクラス定義が出力されます。

0% ruby -rwsdl/soap/classDefCreator -rwsdl/xmlSchema/parser -e 'puts
WSDL::SOAP::ClassDefCreator.new(WSDL::XMLSchema::Parser.new.parse(File.open("enum.xsd")).collect_complextypes).dump'
# urn:org.example.enumsample
class Hobbit
  @@schema_type = "hobbit"
  @@schema_ns = "urn:org.example.enumsample"

  def name
    @name
  end

  def name=(value)
    @name = value
  end

  def age
    @age
  end

  def age=(value)
    @age = value
  end

  def initialize(name = nil,
      age = nil)
    @name = name
    @age = age
  end
end

で、とある人からのリクエストで、enumであるhobbitnameのほうもサポートして
くれと言われているんですが、ここでどう定義を出力したものか、悩んでいます。

1. baseがStringでその値を制限している。そのまま型にしてしまう。

  class Hobbitname < String
    FRODDO = "frodo"
    SAM = "sam"
    MERIADOC = "meriadoc"
    PEREGRIN = "peregrin"
    MEMBER = [FRODO, SAM, MERIADOC, PEREGRIN]

    def initialize(*arg)
      super
      freeze
    end
  end

  こんな気休めなら、enumなんてなくていい気がする。

2. それを使っている側で、値の代入を制限する。あちこちでこの型を使ってい
   る場合は、あちこちにこれを埋め込む。

  class Hobbit
    ...
    def name=(value)
      raise ArgumentError unless MEMBER.include?(value)
      @name = value
    end
    ...
  end

  同じく気休め。

3. クラス定義としてはなにもしない。言語マッピングを適用する際、暗黙のう
   ちに値のチェックを行なって、値域を外れてたらエラーにする。

  str = <<__EOX__
  ...
  <hobbit>
    <name>debujar</name>
    <age>55</age>
  </hobbit>
  __EOX__
  mapper.xml2ruby(str) #=> ArgumentError

3かなぁ。。。