Home Notices Documents Classes Download Others Rice
Documents  >  Development  >  Dynamic embedded classes  >  Fitter
Implementation of fitter

Purpose of this page

This page details the second part of the five part that divided the Rtemplate.cs.



In the part describes here, the _fitter() method is defined. This is an abstract method declared in the definition of Rtype, and must be implemented in a derived class of Rtype. That is, it must be implemented in an embedded class.

The _fitter() method is a method to define the behavior about initialization of instance. Specifically, the fitter called in the new expression is defined by this method.


The first section explains the new expression.

What is important in the _fitter() method is the method's arguments. We will make a section for each argument and explain.

Finally, we will have a section for implementation example and default fitter.

new expression

The new expression is an expression for creating an instance. Here, the new expression is explained using the template class as an example.


new template()


The new expression is an expression starting with the keyword new. A word after new must be the class name. The class name can be either a embedded or user-defined class as long as it is a valid class name. The new expression determines the class of the instance to be generated by this class name. In the above example, template follows after new, so an instance of temlate class is generated.

The class name and the following arguments create the name of the initialization routine to be executed on the instance. The name is called fitter-signature. The rules for creating fitter-signature are described in the next section.

Rice invokes the initialization routine corresponding to the fitter-signature and performs initialization on the generated instance. If the initialization routine corresponding to the fitter-signature does not exist, an exception will occur.

If initialization is successful, the instance is returned as the result of the new expression.


The first argument : string signature

The created fitter-signature is passed to the method as a signature which is the first argument of _fitter().

We will explain fitter-signature generation rules in order by increasing the number of arguments.


No argument

new template()

This is when empty parentheses are specified after the class name in the new expression. In this case, the fitter-signature is template().


One argument. When taking one argument of string class.

new template("Argument string")

The fitter-signature is template(string). If there is only one argument, the class name of the argument will be inserted between parentheses.


Two arguments. When taking arguments of string class and int class.

new template("Argument string", 10)

The fitter-signature is template(string,int). If there are two arguments, The class names that are separated by commas will place between the parentheses in the order of appearance.


Three or more arguments.

It is the same as when two arguments. The class names that are separated by commas will place between the parentheses in the order of appearance.


Please be careful about the class names of container classes - list, dictionary, stack, queue -. These classes can specify a holded class.

For example, the class name of plain list is the "list", but if the string class is kept, the class name is list{string}. The same is true for other container classes.

Please note that this qualified class name appears in the fitter-signature.


template(list)

template(list{string})

The fitter-signature created in this way is passed to the _fitter() method as the first argument.

The second argiment : VirtualMachine vm

An instance of the VirtualMachine class is passed as the second argument. This represents the virtual machine on which the script is running.

The purpose of this argument is to get an instance of the exception class. If you need to throw an exception, get one from VirtualMachine.

For example.


throw vm.GetRtypeException("Message of exception");


Since it is an exception thrown from the _fitter() method, it is appropriate to use the RtypeException class that is assuming class related exceptions. So we get that instance with GetRtypeException() and throw it.

This argument is useful if you want to give a detailed message about the exception. In addition, if you throw an exception from near the place where the exception occurs, additional information will be more accurate. The additional information is location information such as the source file name and the number of lines where the exception occurred. If you get an exception from the VirtualMachine class, that information will be automatically set to the exception.

Even if you throw a normal exception as C#, it will be caught immediately and converted to UnknownException class. The additional information is set automatically at this time.

The third argument : Queue<Rtype> argqueue

The arguments passed in the new expression are stored in argqueue and passed to the _fitter() method.

We will explain the argqueue in order by increasing the number of arguments.


No argument

new template()

In this case, an empty Queue<Rtype> will be passed. Note that it is not null.


One argument. When taking one argument of string class.

new template("Argument string")

The fitter-signature is "template(string)". Therefore, the argqueue holds an instance of Rstring class. In this case, its value is "Argument string".


Two arguments. When taking arguments of string class and int class.

new template("Argument string", 10)

The fitter-signature is "template(string,int)". Therefore, the argqueue holds instances of Rstring class and Rint class. In this case, its value is "Argument string" and 10.

Like this, the argqueue holds arguments in the order of appearance.


Three or more arguments.

It is the same as when two arguments. The argqueue holds arguments in the order of appearance.

Example of Implementation

We can do the necessary initialization using the fact that the fitter-signature is stored in the signature and the actual arguments are stored in the argqueue in the order of appearance.

The following is an implementation example of a fitter without arguments - template() - and a fitter with one string argument - template(string) -.

1:public override bool _fitter(string signature, VirtualMachine vm, Queue<Rtype> argqueue) {
2:switch (signature) {
3:// new template()
4:case TYPENAME + "()": {
5:// Implements necessary code here.
6:return true;
7:}
8:// new template(string)
9:case TYPENAME + "(" + Rstring.TYPENAME + ")": {
10:string arg1 = (Rstring)argqueue.Dequeue();
11:// Implements necessary code here.
12:return true;
13:}
14:default:
15:return false;
16:}
17:}

In this example, the switch statement and the fitter-signature are used to branch. The value of each case can be created by combining the TYPENAME constant of classes. When there are two or more arguments, you can make a case value regardless of the number of arguments if you place "," between the argument's class names.

Actual arguments are stored in argqueue in the order of appearance as instances of the Rtype class which is the base class. That is, the order of the arguments is known, so if you take out from argqueue and cast it to an Rtype derived class, you can get the necessary arguments correctly.

In the above example, it has been implicitly converted to string after casting from Rtype to Rstring. Please refer to the manual or check the object browser of Visual Studio for the cast of the embedded class.

The implementation of the actual embedded class performs necessary initialization after branching in the case. Please note that it returns true when initialization is complete. True indicates that the fitter exists and initialization is successful.

The "default:" returns false. false indicates that class do not have a suitable fitter. An exception will be thrown if false is returned.

Default fitter

The fitter with no arguments is called the default fitter.

The above implementation example explicitly implements the default fitter, but if there is no explicitly implemented default fitter, Rice implements it implicitly (automatically). In other words, you do not have to implement the default fitter if you do not need it. The default fitter that Implicitly implements return the same instance as the one returned by the declaration statement.

Implementation when do not need a fitter

A class does not need a fitter in some cases.

In such a case, implement the _fitter() method as follows.

1:public override bool _fitter(string signature, VirtualMachine vm, Queue<Rtype> argqueue) {
2:return false;
3:}

Next page

It concludes the description of the fitter. If the _fitter() method is implemented correctly, instances of the class will also be created correctly.

The next page describes the implementation of setter.

Next
Previous
Copyright © CookerGX All rights reserved.