rrt_ruby 0.2.1-mswin32 → 0.3.0-mswin32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/rrt_ruby/classes.rb +879 -0
- data/lib/rrt_ruby/finder.rb +264 -0
- data/lib/rrt_ruby/writer.rb +166 -0
- data/lib/rrt_ruby.rb +161 -18
- metadata +5 -6
- data/lib/rrt_ruby/rrt_component.rb +0 -177
- data/lib/rrt_ruby/rrt_deployment.rb +0 -96
- data/lib/rrt_ruby/rrt_generic.rb +0 -229
- data/lib/rrt_ruby/rrt_logical.rb +0 -314
@@ -1,177 +0,0 @@
|
|
1
|
-
#Contains the Component View corresponding elements and Finder functionality.
|
2
|
-
#See RRT_RUBY::RRTComponent
|
3
|
-
|
4
|
-
#
|
5
|
-
RRT_DIR="rrt_ruby/" unless defined?(::RRT_DIR)
|
6
|
-
require RRT_DIR+'rrt_generic'
|
7
|
-
module RRT_RUBY
|
8
|
-
#Adds functionality for accessing the Component View of
|
9
|
-
#a RoseRT model.
|
10
|
-
module RRTComponent
|
11
|
-
#Represents an RRT Component
|
12
|
-
class Component<RRTGeneric::Element
|
13
|
-
attr_reader :platform,:type,:package
|
14
|
-
def initialize element
|
15
|
-
begin
|
16
|
-
super(element)
|
17
|
-
@type=element.Type
|
18
|
-
@platform=element.Platform
|
19
|
-
@package=element.ParentComponentPackage.GetQualifiedName
|
20
|
-
rescue
|
21
|
-
raise RRTGeneric::ElementException.new(element),"error while initialising element: #{$!}"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
def to_s
|
25
|
-
super()+", #{@type}/#{@platform}."
|
26
|
-
end
|
27
|
-
end
|
28
|
-
#A Library Component
|
29
|
-
class Library<Component
|
30
|
-
attr_reader :output_directory,:unit_name
|
31
|
-
|
32
|
-
def initialize element
|
33
|
-
begin
|
34
|
-
super(element)
|
35
|
-
rescue
|
36
|
-
raise RRTGeneric::ElementException.new(element),"error while initialising element: #{$!}"
|
37
|
-
end
|
38
|
-
end
|
39
|
-
def to_s
|
40
|
-
super()
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
#An Executable Component
|
45
|
-
class Executable<Component
|
46
|
-
attr_reader :topcapsule, :filename
|
47
|
-
|
48
|
-
def initialize element
|
49
|
-
begin
|
50
|
-
super(element)
|
51
|
-
@topcapsule=element.FindProperty("OT::CppExec","TopCapsule").Value.sub("[event_ui\r\n\tdescription='","")
|
52
|
-
@topcapsule.sub!(/'\r\n\tcaption='Select.+\n.*/,"")
|
53
|
-
@filename=""
|
54
|
-
|
55
|
-
rescue
|
56
|
-
raise RRTGeneric::ElementException.new(element),"error while initialising element: #{$!}"
|
57
|
-
end
|
58
|
-
end
|
59
|
-
def to_s
|
60
|
-
super()+", #{@topcapsule}."
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
#~ class ExternalLibrary<Component
|
65
|
-
#~ def initialize element
|
66
|
-
#~ begin
|
67
|
-
#~ super(element)
|
68
|
-
#~ rescue
|
69
|
-
#~ raise RRTGeneric::ElementException.new(element),"error while initialising element"
|
70
|
-
#~ end
|
71
|
-
#~ end
|
72
|
-
#~ def to_s
|
73
|
-
#~ super()
|
74
|
-
#~ end
|
75
|
-
#~ end
|
76
|
-
|
77
|
-
#Adds functionality for querying component view elements.
|
78
|
-
module ComponentFinderModule
|
79
|
-
#Delivers all fully qualified component names under the defined package.
|
80
|
-
#If the parameter does not correspond to a component view package it will return an empty array
|
81
|
-
def component_names root_package
|
82
|
-
components=Array.new
|
83
|
-
#first of all find the package in the model
|
84
|
-
pkg= find_component_package(root_package,debug)
|
85
|
-
begin
|
86
|
-
comps=pkg.GetAllComponents
|
87
|
-
@logger.debug("There are #{comps.Count} components under #{pkg.GetQualifiedName}")
|
88
|
-
cnt=comps.Count
|
89
|
-
1.upto(cnt){|i|
|
90
|
-
components<<comps.GetAt(i).GetQualifiedName
|
91
|
-
}
|
92
|
-
end if pkg
|
93
|
-
return components
|
94
|
-
end
|
95
|
-
#Returns all components in the given package
|
96
|
-
def components root_package
|
97
|
-
components=Array.new
|
98
|
-
#first of all find the package in the model
|
99
|
-
pkg= find_component_package(root_package,debug)
|
100
|
-
begin
|
101
|
-
comps=pkg.GetAllComponents
|
102
|
-
@logger.debug("There are #{comps.Count} components under #{pkg.GetQualifiedName}")
|
103
|
-
cnt=comps.Count
|
104
|
-
1.upto(cnt){|i|
|
105
|
-
components<<Component.new(comps.GetAt(i))
|
106
|
-
}
|
107
|
-
end if pkg
|
108
|
-
return components
|
109
|
-
end
|
110
|
-
#Returns all executables in the given package
|
111
|
-
def executables root_package
|
112
|
-
components=Array.new
|
113
|
-
#first of all find the package in the model
|
114
|
-
pkg= find_component_package(root_package,debug)
|
115
|
-
begin
|
116
|
-
comps=pkg.GetAllComponents
|
117
|
-
@logger.debug("There are #{comps.Count} components under #{pkg.GetQualifiedName}")
|
118
|
-
cnt=comps.Count
|
119
|
-
1.upto(cnt){|i|
|
120
|
-
comp=comps.GetAt(i)
|
121
|
-
components<<Executable.new(comp) if comp.Type=~/Executable/
|
122
|
-
}
|
123
|
-
end if pkg
|
124
|
-
return components
|
125
|
-
end
|
126
|
-
#returns all libraries in the given package and it's subpackages
|
127
|
-
def libraries root_package
|
128
|
-
components=Array.new
|
129
|
-
#first of all find the package in the model
|
130
|
-
pkg= find_component_package(root_package,debug)
|
131
|
-
begin
|
132
|
-
comps=pkg.GetAllComponents
|
133
|
-
@logger.debug("There are #{comps.Count} components under #{pkg.GetQualifiedName}")
|
134
|
-
cnt=comps.Count
|
135
|
-
1.upto(cnt){|i|
|
136
|
-
comp=comps.GetAt(i)
|
137
|
-
type=comp.Type
|
138
|
-
components<<Library.new(comp) if type=~/Library/ && !(type=~/External/)
|
139
|
-
}
|
140
|
-
end if pkg
|
141
|
-
return components
|
142
|
-
end
|
143
|
-
#Returns all external libraries in the given package and it's subpackages
|
144
|
-
def external_libraries root_package
|
145
|
-
comps=components(root_package,debug)
|
146
|
-
return comps.collect{|c|
|
147
|
-
c if c.type=~/External/
|
148
|
-
}.compact
|
149
|
-
end
|
150
|
-
#This will return the first component package matching the name, nil if no component package is found.
|
151
|
-
#
|
152
|
-
#If no fully qualified name is provided, then the first match is returned
|
153
|
-
def find_component_package package_name,debug=false
|
154
|
-
#get the simple package name
|
155
|
-
splitted=package_name.split("::")
|
156
|
-
simple_name=splitted[splitted.size-1] unless splitted.size==0
|
157
|
-
#get a collection with all the packages with the same name
|
158
|
-
col=@model.FindModelElements(simple_name)
|
159
|
-
count=col.Count
|
160
|
-
@logger.debug("There are #{count} packages named #{simple_name}")
|
161
|
-
1.upto(count){|i|
|
162
|
-
obj=col.GetAt(i)
|
163
|
-
#match the first if no qualified name is given
|
164
|
-
return obj if package_name==simple_name&&obj.Name==simple_name && obj.IsClass("ComponentPackage")
|
165
|
-
#match the qualified name
|
166
|
-
return obj if obj.GetQualifiedName==package_name && obj.IsClass("ComponentPackage")
|
167
|
-
}
|
168
|
-
return nil
|
169
|
-
end
|
170
|
-
end
|
171
|
-
#This is just for compatibility with the older scripts. The RRTFinder should be used instead.
|
172
|
-
class ComponentFinder<RRTGeneric::Finder
|
173
|
-
include RRTComponent::ComponentFinderModule
|
174
|
-
end
|
175
|
-
|
176
|
-
end
|
177
|
-
end
|
@@ -1,96 +0,0 @@
|
|
1
|
-
#Contains the Deployment View corresponding elements and Finder functionality.
|
2
|
-
#See RRT_RUBY::RRTDeployment
|
3
|
-
|
4
|
-
#
|
5
|
-
RRT_DIR="rrt_ruby/" unless defined?(::RRT_DIR)
|
6
|
-
require RRT_DIR+'rrt_generic'
|
7
|
-
module RRT_RUBY
|
8
|
-
#Adds functionality for accessing the Deployment View of
|
9
|
-
#a RoseRT model.
|
10
|
-
module RRT_RUBY::RRTDeployment
|
11
|
-
class Processor<RRTGeneric::Element
|
12
|
-
attr_reader :cpu,:os,:address,:server,:processes
|
13
|
-
def initialize element
|
14
|
-
begin
|
15
|
-
super(element)
|
16
|
-
@cpu=element.CPU
|
17
|
-
@os=element.OS
|
18
|
-
@address=element.Address
|
19
|
-
@server=element.ServerAddress
|
20
|
-
@processes=Array.new
|
21
|
-
extract_processes(element)
|
22
|
-
rescue
|
23
|
-
raise RRTGeneric::ElementException.new(element),"error while initialising element: #{$!}"
|
24
|
-
end
|
25
|
-
end
|
26
|
-
def to_s
|
27
|
-
return super()+", #{@os}/#{@cpu}, #{@address}, #{@processes.size} processes"
|
28
|
-
end
|
29
|
-
private
|
30
|
-
def extract_processes(element)
|
31
|
-
comps=element.ComponentInstances
|
32
|
-
cnt=comps.Count
|
33
|
-
1.upto(cnt){|i|
|
34
|
-
@processes<<Instance.new(comps.GetAt(i))
|
35
|
-
}
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
class Instance<RRTGeneric::Element
|
40
|
-
def initialize element
|
41
|
-
begin
|
42
|
-
super(element)
|
43
|
-
@component=element.Component
|
44
|
-
rescue
|
45
|
-
raise RRTGeneric::ElementException.new(element),"error while initialising element #{$!}"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
def to_s
|
49
|
-
super()+", #{@component}"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
#Adds functionality for querying deployment view elements.
|
53
|
-
module DeploymentFinderModule
|
54
|
-
#delivers all processors under the defined package.
|
55
|
-
#If the parameter does not correspond to a deployment view package it will return an empty array
|
56
|
-
def processors root_package,debug=false
|
57
|
-
components=Array.new
|
58
|
-
#first of all find the package in the model
|
59
|
-
pkg= find_deployment_package(root_package,debug)
|
60
|
-
begin
|
61
|
-
comps=pkg.GetAllProcessors
|
62
|
-
$stdout.puts("There are #{comps.Count} processors under #{pkg.GetQualifiedName}") if debug
|
63
|
-
cnt=comps.Count
|
64
|
-
1.upto(cnt){|i|
|
65
|
-
components<<Processor.new(comps.GetAt(i))
|
66
|
-
}
|
67
|
-
end if pkg
|
68
|
-
return components
|
69
|
-
end
|
70
|
-
#This will return the first deployment package matching the name
|
71
|
-
#nil if no deployment package is found
|
72
|
-
#if no fully qualified name is provided, then the first match is returned
|
73
|
-
def find_deployment_package package_name,debug=false
|
74
|
-
#get the simple package name
|
75
|
-
splitted=package_name.split("::")
|
76
|
-
simple_name=splitted[splitted.size-1] unless splitted.size==0
|
77
|
-
#get a collection with all the packages with the same name
|
78
|
-
col=@model.FindModelElements(simple_name)
|
79
|
-
count=col.Count
|
80
|
-
$stdout.puts "There are #{count} packages named #{simple_name}" if debug
|
81
|
-
1.upto(count){|i|
|
82
|
-
obj=col.GetAt(i)
|
83
|
-
#match the first if no qualified name is given
|
84
|
-
return obj if package_name==simple_name&&obj.Name==simple_name && obj.IsClass("DeploymentPackage")
|
85
|
-
#match the qualified name
|
86
|
-
return obj if obj.GetQualifiedName==package_name && obj.IsClass("DeploymentPackage")
|
87
|
-
}
|
88
|
-
return nil
|
89
|
-
end
|
90
|
-
end
|
91
|
-
#This is just for compatibility with the older scripts. The RRTFinder should be used instead.
|
92
|
-
class DeploymentFinder<RRTGeneric::Finder
|
93
|
-
include RRTDeployment::DeploymentFinderModule
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
data/lib/rrt_ruby/rrt_generic.rb
DELETED
@@ -1,229 +0,0 @@
|
|
1
|
-
RRT_DIR="rrt_ruby/" unless defined?(::RRT_DIR)
|
2
|
-
require RRT_DIR+'../riva_ruby'
|
3
|
-
module RRT_RUBY
|
4
|
-
#This module provides the namespace for the basic RRT RRTEI Ruby interface.
|
5
|
-
#
|
6
|
-
#It introduces the Finder class as the primary interface for accessing RRT models.
|
7
|
-
#
|
8
|
-
#The module (as well as the others - RRTLogical, RRTComponent, RRTDeployment)
|
9
|
-
#does not provide a one-to-one representation of RRTEI objects, just a convenience mapping
|
10
|
-
#for accessing the most important features of each view.
|
11
|
-
#
|
12
|
-
#We do not attempt to duplicate the interface, just make the most usual tasks easier.
|
13
|
-
module RRT_RUBY::RRTGeneric
|
14
|
-
require 'win32ole'
|
15
|
-
VERSION_MAJOR=1
|
16
|
-
VERSION_MINOR=0
|
17
|
-
OLEAPP_NAME='RoseRT.Application'
|
18
|
-
#This is the base class for all model elements. It corresponds to RRTEI::ModelElement
|
19
|
-
class Element
|
20
|
-
attr_reader :name,:qualifiedname,:stereotype,:documentation
|
21
|
-
#element is the OLE Object of a RRTEI::ModelElement or derived class
|
22
|
-
def initialize element
|
23
|
-
begin
|
24
|
-
@name=element.Name
|
25
|
-
@qualifiedname=element.GetQualifiedName
|
26
|
-
@stereotype=element.Stereotype
|
27
|
-
@documentation=element.Documentation
|
28
|
-
rescue
|
29
|
-
raise ElementException.new(element),"error while initialising element: #{$!}"
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def to_s
|
34
|
-
return "<<#{@stereotype}>>#{@name}"
|
35
|
-
end
|
36
|
-
end
|
37
|
-
#Finder provides an interface for accessing RRT models using OLE Automation.
|
38
|
-
#Finder represents a read-only interface to a model's content, and will remain so in future versions.
|
39
|
-
#
|
40
|
-
#It will create an OLE Instance of RRT on initialization.
|
41
|
-
#
|
42
|
-
#In order to properly release this instance Finder#stop must be called prior to exiting
|
43
|
-
#the Ruby application.
|
44
|
-
#
|
45
|
-
#Alternatively Finder#open can be used with a block.
|
46
|
-
#
|
47
|
-
#RRT under Windows XP (not tested on other versions) only allows three instances. Unfortunately, once an OLE Automation instance
|
48
|
-
#is accessed, references prevent the instances from being destroyed even after stopping a Finder.
|
49
|
-
#
|
50
|
-
#This effectively limits the number of possible Finder instances per application to three.
|
51
|
-
#
|
52
|
-
#Notice that you still need to call stop or use open with a block otherwise the RRT
|
53
|
-
#application will remain in memory after termination of the Ruby application.
|
54
|
-
class Finder
|
55
|
-
include RivaLib::RivaLogger
|
56
|
-
attr_reader :modelname, :model
|
57
|
-
#Initialize will throw an exception if the model cannot be opened.
|
58
|
-
#
|
59
|
-
#Finder uses Logger to log on STDOUT. Optionally you can pass a Logger instance
|
60
|
-
#and it will be used.
|
61
|
-
def initialize modelname="",logger=nil
|
62
|
-
@modelname=modelname
|
63
|
-
@app=WIN32OLE.new(RRTGeneric::OLEAPP_NAME)
|
64
|
-
@model=@app.OpenModel(@modelname) unless modelname.empty?
|
65
|
-
logger_init(logger)
|
66
|
-
end
|
67
|
-
#open is used in conjuction with a block.
|
68
|
-
#
|
69
|
-
#It creates a Finder instance and passes it to the block.
|
70
|
-
#At the end of the block the Finder is stopped and invalidated.
|
71
|
-
#
|
72
|
-
#You can optionally pass a Logger instance to be used by the Finder.
|
73
|
-
#
|
74
|
-
#Without a block the method is just an alias for Finder#new
|
75
|
-
def Finder.open modelname,logger=nil
|
76
|
-
begin
|
77
|
-
fndr=new(modelname,logger)
|
78
|
-
if block_given?
|
79
|
-
begin
|
80
|
-
yield fndr
|
81
|
-
ensure
|
82
|
-
fndr.stop
|
83
|
-
end
|
84
|
-
else
|
85
|
-
return fndr
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
#Instructs the Finder to load a new model into it's associated RRT instance.
|
90
|
-
#
|
91
|
-
#If modelname matches the current modelname or the Finder is invalid...well, nothing will happen.
|
92
|
-
def reload modelname
|
93
|
-
begin
|
94
|
-
@modelname=modelname
|
95
|
-
@model=@app.openmodel(@modelname)
|
96
|
-
end if @app && @app.CurrentModel.GetFileName.upcase!=modelname.upcase
|
97
|
-
end
|
98
|
-
#Stops the Finder releasing the OLE interface and invalidating this Finder instance.
|
99
|
-
#
|
100
|
-
#This method *must* be called to clean up resources unless you used Finder#start with a block.
|
101
|
-
#
|
102
|
-
#If you don't call this method you will end up with a zombie RoserRT instance and a couple of MBs less memory.
|
103
|
-
#
|
104
|
-
#After calling stop the Finder instance cannot be used again (most methods throw a FinderException).
|
105
|
-
#
|
106
|
-
#Unfortunately, there is no control on when the RRT instance is going to exit.
|
107
|
-
#
|
108
|
-
#Usually RRT instances that have been accessed will not exit until the application/script ends.
|
109
|
-
#Since RRT only allows three running instances, this means you can only reload a stopped finder twice.
|
110
|
-
def stop
|
111
|
-
@logger.debug("Stopping Finder")
|
112
|
-
@app.exit if @app
|
113
|
-
@app.ole_free()
|
114
|
-
@model=nil
|
115
|
-
@app=nil
|
116
|
-
end
|
117
|
-
#Shows the RRT UI for the associated OLE instance
|
118
|
-
#Makes the RRT UI associated with the Finder visible.
|
119
|
-
#
|
120
|
-
#Throws a FinderException if no instance exists
|
121
|
-
def show
|
122
|
-
raise FinderException.new(@modelname),"This Finder instance is invalid" unless @model
|
123
|
-
@app.visible=true
|
124
|
-
end
|
125
|
-
#Hides the RRT UI for the associated OLE instance.
|
126
|
-
#
|
127
|
-
#Throws a FinderException if no instance exists
|
128
|
-
def hide
|
129
|
-
raise FinderException.new(@modelname),"This Finder instance is invalid" unless @model
|
130
|
-
@app.visible=false
|
131
|
-
end
|
132
|
-
#returns the name of the model with which the finder is connected
|
133
|
-
#Alias for LogicalFinder#modelname
|
134
|
-
def name
|
135
|
-
return @modelname
|
136
|
-
end
|
137
|
-
def to_s
|
138
|
-
return "Active on #{@modelname}" if @model
|
139
|
-
return "Invalid for #{@modelname}"
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
#This is a convenience method that makes some assumptions about the use of the win32ole interface.
|
144
|
-
#
|
145
|
-
#It is here to be used with scripts that don't need the full Finder functionality or want to work directly with the RRTEI interface.
|
146
|
-
#
|
147
|
-
#It only takes a block to make sure we clean up the application object afterwards.
|
148
|
-
#This cleanup has a sideeffect: open RRT instances will be closed after the block finishes.
|
149
|
-
#
|
150
|
-
#RRT only seems to create one OLE application server (instance started with this session do not register as OLE servers).
|
151
|
-
def RRTGeneric.open_model pathname,logger=nil
|
152
|
-
#opens the model with the given pathname and returns a reference to the Win32OLE model object.
|
153
|
-
#first check the pathname
|
154
|
-
if File.exists?(pathname) then
|
155
|
-
#check if there is an open RRT instance with this model
|
156
|
-
begin
|
157
|
-
rt = WIN32OLE.connect(RRTGeneric::OLEAPP_NAME)
|
158
|
-
rescue
|
159
|
-
#no OLE Server present, create a new instance
|
160
|
-
logger.info("No OLE Server found. Creating new instance") if logger
|
161
|
-
rt=WIN32OLE.new(RRTGeneric::OLEAPP_NAME)
|
162
|
-
end
|
163
|
-
begin
|
164
|
-
# We are in Windows so filenames are case insensitive
|
165
|
-
if rt.CurrentModel.GetFileName.upcase==pathname.upcase
|
166
|
-
logger.debug("Using existing model") if logger
|
167
|
-
model = rt.CurrentModel
|
168
|
-
#it was open before, so don't close the app at the end
|
169
|
-
exit_app=false
|
170
|
-
else
|
171
|
-
logger.info("Opening model") if logger
|
172
|
-
model=rt.openmodel(pathname)
|
173
|
-
exit_app=true
|
174
|
-
end
|
175
|
-
yield model
|
176
|
-
ensure
|
177
|
-
if rt && exit_app
|
178
|
-
rt.exit
|
179
|
-
rt.ole_free()
|
180
|
-
end
|
181
|
-
end
|
182
|
-
return model
|
183
|
-
else
|
184
|
-
logger.fatal("File not found #{pathname}") if logger
|
185
|
-
end if block_given?
|
186
|
-
end
|
187
|
-
#Given a valid model (OLE object) it will return the first OLE object matching name and type.
|
188
|
-
#
|
189
|
-
#This wraps the FindModelElements method of the RRTEI API.
|
190
|
-
def RRTGeneric.find_element model,name,type
|
191
|
-
raise FinderException.new(""),"no model specified" unless model
|
192
|
-
col=model.FindModelElements(name)
|
193
|
-
count=col.Count
|
194
|
-
1.upto(count){|i|
|
195
|
-
it=col.GetAt(i)
|
196
|
-
return it if it && it.Name==name && it.IsClass(type)
|
197
|
-
}
|
198
|
-
return nil
|
199
|
-
end
|
200
|
-
|
201
|
-
#Returns the pathname for the current model if an OLE server is present, nil otherwise
|
202
|
-
def RRTGeneric.current_model
|
203
|
-
begin
|
204
|
-
rt = WIN32OLE.connect(RRTGeneric::OLEAPP_NAME)
|
205
|
-
return rt.CurrentModel.GetFileName
|
206
|
-
rescue
|
207
|
-
return nil
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
class ModelException<RuntimeError
|
212
|
-
def initialize(model)
|
213
|
-
@model=model
|
214
|
-
end
|
215
|
-
end
|
216
|
-
class ElementException<RuntimeError
|
217
|
-
def initialize element
|
218
|
-
@element=element
|
219
|
-
end
|
220
|
-
end
|
221
|
-
class FinderException<RuntimeError
|
222
|
-
attr_reader :modelname
|
223
|
-
def initialize modelname
|
224
|
-
super
|
225
|
-
@modelname=modelname
|
226
|
-
end
|
227
|
-
end
|
228
|
-
end
|
229
|
-
end
|