Scenario,
If we trying to pass multiple type of class instances to a function,
then how do we check whether the passed instances are model instance or not
without providing explicit Class names in it?
Related
I am writing verification IP for some interface and facing with one interesting item, which I think is somehow basic for OOP.
So in my driver I have functions e.g. configMaster, which is DUT specific. And VIP user may want to override that function. Now I want to provide mechanism for user to do that.
I think the best way of overriding the VIP driver class functions would be following
User extends the driver class
In the extended class user redefines the driver methods that he wants. If there are several methods that user doesn’t want to override that’s fine.
Using factory override method user overrides the driver class with the
extended user_driver class
The thing I don’t like here that user each time running the simulation should specify the factory override command.
Could you please share your opinion is this right way to do? Are there other ways?
Thanks
Hayk
Step 3 is not always mandatory . After overriding the class the user can directly use the derived class in his TB. This will mostly be the case if the TB is being built afresh or the user is integrating this IP as a new component into an existing TB.
In case the VIP was already present in a TB and you are now providing new set of functions to the user to override or the user itself want to use the override mechanism preferring to instantiate the base class provided by the VIP and use the override mechanism later , user can use the set_type_override_by_type function .
The function can be embedded into a base test and all the derived test will implicitly use the use vip class derived by the user without the need to specify it explicitly in the command line for each test case.
There are 4 flavor to the type override function .
http://www.testbench.in/UT_06_UVM_FACTORY.html
The function can also be used in a base env too , the user has to ensure that the type override function is called before the class is create for the override mechanism to take effect.
I've been trying to find some info on difference between instantiating form fields through static method and the new keyword. Can somebody tell me what are the practical implications, limitations, between new MyFormField and MyFormField::create() esp. with regards to SilverStripe
Using the create factory method would check for overloads (set via Object::useCustomClass()) and return an instance of the custom class in that case.
This method first for strong class overloads (singletons & DB
interaction), then custom class overloads. If an overload is found, an
instance of this is returned rather than the original class. To
overload a class, use Object::useCustomClass()
So using the create method rather than instantiating the Object yourself would provide a possibility to overload the used Class without altering the code.
see
http://api.silverstripe.org/3.1/class-Object.html#_useCustomClass
http://api.silverstripe.org/3.1/class-Object.html#_create
class class_name = new class();
this is how we define and instantiate objects in java.
My question is: What is the role played here by the constructor 'class()' here in this statement.
The constructor provides the chance to have some code run as the new object is instantiated.
Common uses for constructors are to set default properties, to establish an environment within which the object can operate (gathering resources etc...), registering Event Handlers (Listeners for the Java minded...)
Constructor is used to initialize member variables of a class and prepare object for use. If you don't define your own, Java will generate default constructor, initializing member variables to default values (e.g 0 for int, null for object references). Java Object can have multiple constructors with different parameters. Constructors are similar to methods, but have no return type and their name must match name of the class.
see http://en.wikipedia.org/wiki/Constructor_%28object-oriented_programming%29#Java
I'm writing a variety of Model Tests in CakePHP (PHPUnit)
In TravisCI, I get something like: "Base table or view not found: 1146 Table 'test.events'
In Cake's test runner I get an assertion failure.
The problem I am having is there are methods in my ModelClasses that I am trying to test which call other models with App::uses. For example:
Method on User model:
public function getOtherData() {
App::uses('Event', 'Model');
$this->Event = new Event;
return $this->Event->find('all');
}
And the test:
public function testGetOtherData() {
$result = $this->User->getOtherData();
$this->assertTrue(!empty($result));
}
Note the above example is just that. An example, simplified to show the problem. I understand that the above example has better 'cake' ways of doing it.
Also, I am using defining required fixtures and they work just fine. (I know this by another method in the model which uses a join in the find, instead of App::Uses())
EDIT:
The code when run works, BUT the UnitTest is looking for the other models data (When using App::uses) in the default database, and not the test database. Why doesn't it use the test database? Am I missing something?
LAST NOTE
Using App::uses() and then instantiating the class will work at runtime. But during testing it will fail, as it attempts to use the default database connection, instead of the test database connection.
Per the selected answer, rather than using App::uses, Cakes built in class registry, ClassRegistry::init('Model', true);, you can include a Model from inside another model method.
It's not generally a good idea to instantiate an object in the middle of your functions using the new statement. This is why -- there's no way to block or redirect that call. Also, it's not necessarily easy to get the right parameters to the object's constructor when it's in the middle of another function, so it's best to keep that code separate.
The right way to do this is to use a different method call to get your object. If you use Cake's ClassRegistry::init() to create model objects, they should use the test database.
If you need to create other non-Cake objects, it's best to create them using some other function, e.g. $this->fetchMeOneOThemEventThingies(). Then, during testing, you can mock out that function and have it return something else. Or, you could use some other DI container like pimple, which will take the same role as Cake's ClassRegistry.
If you need a mock model object for testing, be sure to pass the appropriate arguments to the model's constructor as the third parameter to getMock(), or it may use the production database.
If you use an object database, what happens when you need to change the structure of your object model?
For instance, I'm playing around with the Google App Engine. While I'm developing my app, I've realized that in some cases, I mis-named a class, and I want to change the name. And I have two classes that I think I need to consolidate.
However,I don't think I can, because the name of the class in intuitively tied into the datastore, and there is actual data stored under those class names.
I suppose the good thing about the "old way" of abstracting the object model from the data storage is that the data storage doesn't know anything about the object model --it's just data. So, you can change your object model and just load the data out of the datastore differently.
So, in general, when using a datastore which is intimate with your data model...how do you change things around?
If it's just class naming you're concerned about, you can change the class name without changing the kind (the identifier that is used in the datastore):
class Foo(db.Model):
#classmethod
def kind(cls):
return 'Bar'
If you want to rename your class, just implement the kind() method as above, and have it return the old kind name.
If you need to make changes to the actual representation of data in the datastore, you'll have to run a mapreduce to update the old data.
The same way you do it in relational databases, except without a nice simple SQL script: http://code.google.com/appengine/articles/update_schema.html
Also, just like the old days, objects without properties don't automatically get defaults and properties that don't exist in the schema still hang around as phantoms in the objects.
To rename a property, I expect you can remove the old property (the phantom hangs around) add the new name, populate the data with a copy from the old (phantom) property. The re-written object will only have the new property
You may be able to do it the way we are doing it in our project:
Before we update the object-model (schema), we export our data to a file or blob in json format using a custom export function and version tag on top. After the schema has been updated we import the json with another custom function which creates new entities and populates them with old data. Of course the import version needs to know the json format associated with each version number.