wbem 0.3.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.rdoc +20 -0
- data/Gemfile +2 -0
- data/MIT-LICENSE +22 -0
- data/Rakefile +6 -0
- data/bin/genclassinfo +59 -0
- data/lib/wbem.rb +8 -4
- data/lib/wbem/cimxml.rb +73 -1
- data/lib/wbem/class_factory.rb +163 -0
- data/lib/wbem/class_template.erb +48 -0
- data/lib/wbem/conversion.rb +173 -0
- data/lib/wbem/openwsman.rb +51 -0
- data/lib/wbem/version.rb +1 -1
- data/lib/wbem/wbem.rb +108 -4
- data/lib/wbem/wsman.rb +58 -168
- data/lib/wbem/wsman_instance.rb +148 -0
- data/samples/amt.rb +129 -0
- data/samples/enum.rb +34 -0
- data/samples/get.rb +47 -0
- data/tasks/clean.rake +2 -0
- data/tasks/doc.rake +15 -0
- data/tasks/test.rake +6 -0
- data/test/helper.rb +3 -0
- data/test/test_class_factory.rb +25 -0
- data/test/test_classnames.rb +68 -0
- data/test/test_connect.rb +91 -0
- data/test/test_epr.rb +27 -0
- data/test/test_loading.rb +13 -0
- data/test/test_namespaces.rb +28 -0
- data/test/test_product.rb +56 -0
- data/test/test_profiles.rb +33 -0
- data/test/test_services.rb +33 -0
- data/test/test_systems.rb +34 -0
- data/wbem.gemspec +37 -0
- metadata +76 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a9c0a1ba0bac70d9aa7e910153bf46837a6dd305
|
4
|
+
data.tar.gz: 232a5e958d2e5456ba907379228e0304a32ae82c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 364d2f6af56cfc32aecf396f546aaa85461d0dbb1f123a5db9d9e2f6c2dfc722da657df5db9378d3f52e8b7ef092b71a8ebbe7406d90113f3739bce5d63539ff
|
7
|
+
data.tar.gz: c4d5401ac945660197fa4cb0340da43086a638236d0828be2e3cb61010db996a793fc7d62604d59d678ab0f544437917d33e3d6a1bd7819768dbb0d17c55d332
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
== 0.5.0
|
2
|
+
|
3
|
+
* Add client.get for fetching instances with keys in Cimxml
|
4
|
+
|
5
|
+
== 0.4.0
|
6
|
+
|
7
|
+
* Add bin/genclassinfo to generate Ruby classes from MOF
|
8
|
+
* Add client.get for fetching instances with keys in Wsman
|
9
|
+
* Properly handle EndpointReferences
|
10
|
+
* Add Instance#invoke, based on type information from generated Ruby
|
11
|
+
class
|
12
|
+
|
13
|
+
== 0.3.2
|
14
|
+
|
15
|
+
* Add Client#get to get an instance by ObjectPath
|
16
|
+
|
17
|
+
== 0.3.1
|
18
|
+
|
19
|
+
* Add Client#get to get an instance by EndPointReference
|
20
|
+
|
1
21
|
== 0.3.0
|
2
22
|
|
3
23
|
* Add Client#profiles to enumerate CIM_RegisteredProfile
|
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
Copyright (c) 2009 Novell Inc.
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
a copy of this software and associated documentation files (the
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
data/Rakefile
ADDED
data/bin/genclassinfo
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# genclassinfo
|
4
|
+
#
|
5
|
+
# Generate Ruby class templates
|
6
|
+
#
|
7
|
+
# Copyright (c) 2015 Klaus Kämpf <kkaempf@suse.de>
|
8
|
+
#
|
9
|
+
# Licensed under the Ruby license
|
10
|
+
#
|
11
|
+
# == Usage
|
12
|
+
#
|
13
|
+
# genclassinfo [-d] [-h] [-q] [-I <includedir>] [-o <output>] <moffile> [<moffile> ...]
|
14
|
+
#
|
15
|
+
# -d:
|
16
|
+
# turn on debugging
|
17
|
+
# -h:
|
18
|
+
# show (this) help
|
19
|
+
# -q:
|
20
|
+
# be quiet
|
21
|
+
# -I <includedir>
|
22
|
+
# additional include directories to search
|
23
|
+
# -o <outputdir>
|
24
|
+
# directory to write generated files, defaults to 'generated'
|
25
|
+
# <moffile>
|
26
|
+
# .mof files to read
|
27
|
+
#
|
28
|
+
|
29
|
+
require 'rubygems'
|
30
|
+
|
31
|
+
require 'mof'
|
32
|
+
require 'pathname'
|
33
|
+
require 'fileutils'
|
34
|
+
|
35
|
+
$:.push(File.join(File.dirname(__FILE__), '..', 'lib'))
|
36
|
+
|
37
|
+
require 'wbem'
|
38
|
+
|
39
|
+
def usage msg=nil
|
40
|
+
STDERR.puts "Err: #{msg}" if msg
|
41
|
+
STDERR.puts "Usage: genclassinfo [-d] <class> [ <class> ...]"
|
42
|
+
exit (msg)?1:0
|
43
|
+
end
|
44
|
+
|
45
|
+
#--------------------------------------------------------------------
|
46
|
+
|
47
|
+
@factory = Wbem::ClassFactory.new
|
48
|
+
|
49
|
+
if ARGV.empty?
|
50
|
+
usage
|
51
|
+
end
|
52
|
+
|
53
|
+
ARGV.each do |c|
|
54
|
+
if c == "-d"
|
55
|
+
Wbem::debug = 1
|
56
|
+
next
|
57
|
+
end
|
58
|
+
@factory.gen_class c
|
59
|
+
end
|
data/lib/wbem.rb
CHANGED
@@ -9,6 +9,10 @@
|
|
9
9
|
# Licensed under the MIT license
|
10
10
|
#
|
11
11
|
module Wbem
|
12
|
+
require 'wbem/class_factory'
|
13
|
+
require 'wbem/conversion'
|
14
|
+
require 'wbem/wbem'
|
15
|
+
|
12
16
|
@@debug = nil
|
13
17
|
def Wbem.debug
|
14
18
|
@@debug
|
@@ -19,8 +23,6 @@ module Wbem
|
|
19
23
|
|
20
24
|
class Client
|
21
25
|
require 'uri'
|
22
|
-
require 'wbem/wsman'
|
23
|
-
require 'wbem/cimxml'
|
24
26
|
|
25
27
|
#
|
26
28
|
# Wbem::Client.connect uri, protocol = nil
|
@@ -32,7 +34,7 @@ module Wbem
|
|
32
34
|
# else - probe connection (cim/xml first)
|
33
35
|
#
|
34
36
|
def self.connect uri, protocol = nil, auth_scheme = nil
|
35
|
-
STDERR.puts "Wbem::Client.connect(#{uri},#{protocol},#{auth_scheme})"
|
37
|
+
STDERR.puts "Wbem::Client.connect(#{uri},#{protocol},#{auth_scheme})" if Wbem.debug
|
36
38
|
unless uri.is_a?(URI)
|
37
39
|
u = URI.parse(uri)
|
38
40
|
# u.port will be set in any case, so check the uri for port specification
|
@@ -46,16 +48,18 @@ module Wbem
|
|
46
48
|
unless protocol_given
|
47
49
|
u.port = (u.scheme == "http") ? 5985 : 5986
|
48
50
|
end
|
51
|
+
require 'wbem/wsman'
|
49
52
|
return WsmanClient.new u, auth_scheme
|
50
53
|
when "cimxml"
|
51
54
|
unless protocol_given
|
52
55
|
u.port = (u.scheme == "http") ? 5988 : 5989
|
53
56
|
end
|
57
|
+
require 'wbem/cimxml'
|
54
58
|
return CimxmlClient.new u
|
55
59
|
end
|
56
60
|
# no connect, check known ports
|
57
61
|
case u.port
|
58
|
-
when 8888, 8889, 5985, 5986
|
62
|
+
when 8888, 8889, 5985, 5986, 16992
|
59
63
|
return Wbem::Client.connect u, :wsman, auth_scheme
|
60
64
|
when 5988, 5989
|
61
65
|
return Wbem::Client.connect u, :cimxml, auth_scheme
|
data/lib/wbem/cimxml.rb
CHANGED
@@ -51,6 +51,43 @@ private
|
|
51
51
|
|
52
52
|
public
|
53
53
|
|
54
|
+
#
|
55
|
+
# parse ObjectPath to Sfcc::Cim::ObjectPath
|
56
|
+
# 1. root/cimv2:Linux_ComputerSystem.CreationClassName="Linux_ComputerSystem",Name="foo.bar"
|
57
|
+
# 2. localhost:5989/root/cimv2:Linux_ComputerSystem.CreationClassName="Linux_ComputerSystem",Name="heron.suse.de"
|
58
|
+
#
|
59
|
+
#
|
60
|
+
def self.parse_object_path s
|
61
|
+
op = nil
|
62
|
+
front, values = s.split(".",2)
|
63
|
+
STDERR.puts "self.parse_object_path >#{front}<(#{values})"
|
64
|
+
frontargs = front.split(":")
|
65
|
+
if frontargs.size == 2
|
66
|
+
# case 1 above
|
67
|
+
namespace, classname = frontargs
|
68
|
+
op = Sfcc::Cim::ObjectPath.new(namespace, classname)
|
69
|
+
elsif frontargs.size == 3
|
70
|
+
host, port_and_namespace, classname = frontargs
|
71
|
+
port, namespace = port_and_namespace.split("/", 2)
|
72
|
+
op = Sfcc::Cim::ObjectPath.new(namespace, classname)
|
73
|
+
else
|
74
|
+
raise "CimxmlClient.parse_object_path: Can't parse >#{frontargs.inspect}<"
|
75
|
+
end
|
76
|
+
# add values
|
77
|
+
while values && !values.empty?
|
78
|
+
puts "Values >#{values.inspect}<"
|
79
|
+
name, rest = values.split("=", 2)
|
80
|
+
arg, values = if rest[0,1] == '"' # quoted arg
|
81
|
+
rest[1..-1].split(/\",?/, 2)
|
82
|
+
else # non-quoted arg
|
83
|
+
rest.split(",", 2)
|
84
|
+
end
|
85
|
+
puts "name(#{name}), arg(#{arg})"
|
86
|
+
op.add_key(name, arg)
|
87
|
+
end
|
88
|
+
puts "Op #{op}"
|
89
|
+
op
|
90
|
+
end
|
54
91
|
#
|
55
92
|
# Initialize a CIMXML client connection
|
56
93
|
#
|
@@ -125,10 +162,12 @@ public
|
|
125
162
|
# @param properties : Hash (optional)
|
126
163
|
#
|
127
164
|
def instance_names namespace, classname=nil, properties={}
|
165
|
+
# if namespace is unset, sfcc will generate invalid XML
|
166
|
+
namespace ||= "root/cimv2"
|
128
167
|
case namespace
|
129
168
|
when Sfcc::Cim::ObjectPath
|
130
169
|
objectpath = namespace
|
131
|
-
namespace = objectpath.namespace
|
170
|
+
namespace = objectpath.namespace
|
132
171
|
else
|
133
172
|
objectpath = objectpath namespace.to_s, classname, properties
|
134
173
|
end
|
@@ -143,6 +182,32 @@ public
|
|
143
182
|
ret
|
144
183
|
end
|
145
184
|
|
185
|
+
#
|
186
|
+
# get instance by reference
|
187
|
+
#
|
188
|
+
# call-seq
|
189
|
+
# get Sfcc::Cim::ObjectPath -> Wbem::Instance
|
190
|
+
# get ObjectPath-as-String -> Wbem::Instance
|
191
|
+
# get "ClassName", "key" => "value", :namespace => "root/interop"
|
192
|
+
#
|
193
|
+
def get instance_reference, keys = nil
|
194
|
+
if keys
|
195
|
+
namespace = keys.delete(:namespace) || "root/cimv2"
|
196
|
+
instance_reference = Sfcc::Cim::ObjectPath.new(namespace, instance_reference)
|
197
|
+
keys.each do |k,v|
|
198
|
+
instance_reference.add_key k, v
|
199
|
+
end
|
200
|
+
end
|
201
|
+
puts "@client.get #{instance_reference.class}..." if Wbem.debug
|
202
|
+
case instance_reference
|
203
|
+
when Sfcc::Cim::ObjectPath
|
204
|
+
get_by_objectpath instance_reference
|
205
|
+
when String
|
206
|
+
get_by_objectpath CimxmlClient.parse_object_path(instance_reference)
|
207
|
+
else
|
208
|
+
raise "Unsupported Wbem::get #{instance_reference.class}"
|
209
|
+
end
|
210
|
+
end
|
146
211
|
#
|
147
212
|
# Return matching Wbem::Instance for first instance
|
148
213
|
# matching namespace, classname, properties
|
@@ -190,5 +255,12 @@ public
|
|
190
255
|
end
|
191
256
|
end
|
192
257
|
|
258
|
+
#
|
259
|
+
# get instance by objectpath
|
260
|
+
#
|
261
|
+
def get_by_objectpath objpath
|
262
|
+
STDERR.puts "#{self.class}.get_by_objectpath #{objpath}" if Wbem.debug
|
263
|
+
@client.get_instance(objpath)
|
264
|
+
end
|
193
265
|
end # class
|
194
266
|
end # module
|
@@ -0,0 +1,163 @@
|
|
1
|
+
#
|
2
|
+
# Class Factory
|
3
|
+
#
|
4
|
+
#
|
5
|
+
# Creates CIM class with ancestry chain
|
6
|
+
#
|
7
|
+
# Base class: Wbem::Instance
|
8
|
+
#
|
9
|
+
module Wbem
|
10
|
+
class ClassFactory
|
11
|
+
MOFBASE = "/usr/share/mof/cim-current"
|
12
|
+
AMTBASE = "/usr/share/mof/iAMT/MOF"
|
13
|
+
QUALIFIERS = "qualifiers.mof"
|
14
|
+
SCHEMATA = { MOFBASE => "CIM_Schema.mof", AMTBASE => "amt.mof" }
|
15
|
+
CLASSDIR = "wbem"
|
16
|
+
require 'cim'
|
17
|
+
require 'mof'
|
18
|
+
require 'pathname'
|
19
|
+
|
20
|
+
#
|
21
|
+
# Constructor
|
22
|
+
#
|
23
|
+
def initialize basepath = nil
|
24
|
+
@basedir = File.expand_path(File.join(basepath || Dir.getwd, CLASSDIR))
|
25
|
+
end
|
26
|
+
private
|
27
|
+
|
28
|
+
#
|
29
|
+
# parse_with_ancestors
|
30
|
+
#
|
31
|
+
# Find the superclass name of a class, parse its mof file
|
32
|
+
# returns Hash of { classname -> CIM::Class }
|
33
|
+
#
|
34
|
+
|
35
|
+
def parse_with_ancestors name
|
36
|
+
# find .mof file
|
37
|
+
mofdata = classmap()[name]
|
38
|
+
unless mofdata
|
39
|
+
raise "Can't find MOF for #{name}"
|
40
|
+
end
|
41
|
+
mofpath = mofdata[:path]
|
42
|
+
# parsed before ?
|
43
|
+
mof = mofdata[:mof] rescue nil
|
44
|
+
unless mof
|
45
|
+
# not parsed, parse now
|
46
|
+
puts "Reading mof from #{mofpath}" if Wbem.debug
|
47
|
+
begin
|
48
|
+
mofs = parser().parse [ QUALIFIERS, "qualifiers_intel.mof", mofpath ]
|
49
|
+
rescue Exception => e
|
50
|
+
parser.error_handler e
|
51
|
+
end
|
52
|
+
# puts "==> #{mofs.inspect}"
|
53
|
+
# Iterate over all parsed classes
|
54
|
+
mofs[mofpath].classes.each do |mofclass|
|
55
|
+
next unless mofclass.name == name
|
56
|
+
classmap()[name] = { :path => mofpath, :mof => mofclass }
|
57
|
+
if mofclass.superclass
|
58
|
+
parse_with_ancestors mofclass.superclass
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# generate method parameter information
|
66
|
+
# return nil if no parameters
|
67
|
+
#
|
68
|
+
def gen_method_parameters direction, parameters, file
|
69
|
+
return if parameters.empty?
|
70
|
+
file.print "#{direction.inspect} => ["
|
71
|
+
first = true
|
72
|
+
parameters.each do |p|
|
73
|
+
if first
|
74
|
+
first = false
|
75
|
+
else
|
76
|
+
file.print ", "
|
77
|
+
end
|
78
|
+
# [ <name>, <type>, <out>? ]
|
79
|
+
file.print "#{p.name.inspect}, #{p.type.to_sym.inspect}"
|
80
|
+
end
|
81
|
+
file.print "]"
|
82
|
+
return true
|
83
|
+
end
|
84
|
+
#
|
85
|
+
# generate .rb class declaration
|
86
|
+
#
|
87
|
+
def generate name, file
|
88
|
+
require 'erb'
|
89
|
+
template = File.read(File.join(File.dirname(__FILE__), "class_template.erb"))
|
90
|
+
erb = ERB.new(template)
|
91
|
+
code = erb.result(binding)
|
92
|
+
Dir.mkdir(@basedir) unless File.directory?(@basedir)
|
93
|
+
File.open(file, "w+") do |f|
|
94
|
+
f.puts code
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
#
|
99
|
+
# classmap - generate map of classes and their .mof files
|
100
|
+
#
|
101
|
+
def classmap
|
102
|
+
return @classmap if @classmap
|
103
|
+
# read SCHEMA and build class index to find .mof files quickly
|
104
|
+
@classmap = Hash.new
|
105
|
+
@includes = [ Pathname.new(".") ]
|
106
|
+
SCHEMATA.each do |base, file|
|
107
|
+
@includes << base
|
108
|
+
allow_cim = (file =~ /^CIM_/) # allow CIM_ only for CIM_Schema.mof
|
109
|
+
File.open(File.join(base, file)) do |f|
|
110
|
+
f.each do |l|
|
111
|
+
if l =~ /^\#pragma\sinclude\s?\(\"(([\w\/_]+)\.mof)\"\).*/
|
112
|
+
# $1 Foo/Bar.mof
|
113
|
+
# $2 Foo/Bar
|
114
|
+
path = $1
|
115
|
+
names = $2.split("/")
|
116
|
+
name = names[1] || names[0]
|
117
|
+
next unless name =~ /_/ # class name must have underscore (rules out 'qualifiers.mof')
|
118
|
+
# puts "#{path}:#{name}"
|
119
|
+
next if !allow_cim && name =~ /^CIM_/ # skip CIM_ mofs unless allowed
|
120
|
+
if @classmap[name]
|
121
|
+
raise "Dup #{name} : #{@classmap[name]}"
|
122
|
+
else
|
123
|
+
@classmap[name] = { :path => path }
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
STDERR.puts "Found MOFs for #{@classmap.size} classes" if Wbem.debug
|
130
|
+
@classmap
|
131
|
+
end
|
132
|
+
|
133
|
+
#
|
134
|
+
# MOF parser access
|
135
|
+
#
|
136
|
+
def parser
|
137
|
+
@parser ||= MOF::Parser.new :style => :cim, :includes => @includes, :quiet => true
|
138
|
+
end
|
139
|
+
public
|
140
|
+
#
|
141
|
+
# Class Factory
|
142
|
+
#
|
143
|
+
def class_for name
|
144
|
+
begin
|
145
|
+
path = "#{@basedir}/#{name}"
|
146
|
+
require path
|
147
|
+
return Object.const_get("Wbem").const_get(name)
|
148
|
+
rescue LoadError
|
149
|
+
raise "'#{path}.rb' not found, use 'genclass' of ruby-wbem to generate class '#{name}'"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
#
|
153
|
+
# gen_class
|
154
|
+
#
|
155
|
+
def gen_class name
|
156
|
+
mofname = name + ".mof"
|
157
|
+
classpath = File.join(@basedir, "#{name}.rb")
|
158
|
+
parse_with_ancestors name
|
159
|
+
generate name, classpath
|
160
|
+
class_for name
|
161
|
+
end # def create
|
162
|
+
end # class ClassFactory
|
163
|
+
end # module Wbem
|
@@ -0,0 +1,48 @@
|
|
1
|
+
<%
|
2
|
+
# @classes[name] = { :path => mofpath, :mof => mofclass }
|
3
|
+
|
4
|
+
def collect_superclasses name
|
5
|
+
classdata = @classmap[name]
|
6
|
+
raise "No such class: #{name}" unless classdata
|
7
|
+
mofclass = classdata[:mof]
|
8
|
+
superclass = mofclass.superclass
|
9
|
+
[mofclass] + ((superclass)?collect_superclasses(superclass):[])
|
10
|
+
end
|
11
|
+
%>
|
12
|
+
|
13
|
+
# Class information for <%= name %>
|
14
|
+
# Generated by 'wbem' for use with ruby-wbem
|
15
|
+
|
16
|
+
require 'rubygems'
|
17
|
+
require 'cim'
|
18
|
+
require 'wbem'
|
19
|
+
|
20
|
+
module Wbem
|
21
|
+
|
22
|
+
class <%= name %> < Wbem::Instance
|
23
|
+
<% classes = collect_superclasses name %>
|
24
|
+
<% known_features = Hash.new %>
|
25
|
+
TYPEMAP = {
|
26
|
+
<% classes.each do |mofclass|
|
27
|
+
mofclass.features.each do |f|
|
28
|
+
next if known_features[f.name]
|
29
|
+
known_features[f.name] = f
|
30
|
+
if f.method? %>
|
31
|
+
# <%= mofclass.name %>.<%= f.name %>()
|
32
|
+
<%= f.name.inspect %> => [ <%= f.type.to_sym.inspect %>, <% f.parameters.each do |p| %>
|
33
|
+
[ <%= p.name.inspect %>, <%= p.type.to_sym.inspect %>, <%= (p.includes?(:out))?":out":":in" %> ], <% end %>
|
34
|
+
],
|
35
|
+
<% else %>
|
36
|
+
# <%= mofclass.name %>.<%= f.name %>
|
37
|
+
<%= f.name.inspect %> => <%= f.type.to_sym.inspect %>,
|
38
|
+
<% end
|
39
|
+
end
|
40
|
+
end %>
|
41
|
+
}
|
42
|
+
|
43
|
+
def _typemap
|
44
|
+
TYPEMAP
|
45
|
+
end
|
46
|
+
|
47
|
+
end # class
|
48
|
+
end # module
|