How can getter/setter code be generated automatically for a class in Pharo or Squeak? - code-generation

I have a long list of instance variables to create for a class that I want to generate the code for, rather than do it by hand. The list comes from an existing SQL database. My intention is to do it all in a pure object-oriented way with Smalltalk first, and as I learn more, save the data back to the database and work from it directly.
Is there a way of passing the list of names to method that will generate them and add them to the class definition?
In fact is there a way of adding or modifying class definitions dynamically in Smalltalk? I suspect there must and I would like to know a best practices approach.
Update: What I have in mind is more like passing a list of the instance variables to a method that will create them automatically.
It is more like:
addVariablesAndAccessors className: MyClass variablesList: ('aaaa', 'bbbb', 'cccc')
which will then result in a call to
AddVariables className: MyClass variableList: ('aaaa' 'bbbb' cccc')
and
generateAccessors className: MyClass variableList: ('aaaa' 'bbbb' cccc')

In OmniBrowser with the refactoring tools loaded you select the class and in the context menu Refactor class > Accessors.
Alternatively, if you only want to create an accessor for a single variable, select Refactor instance/class variable > Accessor, and select the variable you want to access.

In Squeak, you have Behavior>>addInstVarName: aString, so for instance, you could do something like:
String addInstVarName: 'foo'
Squeak also has refactoring support to generate accessors automatically. You can either use it directly or have a look at AbstractInstanceVariableRefactoring>>createAccessors to get some inspiration on how to implement your own ;-)
Another quite hacky but not so uncommon solution would be to just generate the instance variables, but instead of adding accessors, you overwrite doesNotUnderstand:, which gets called when an undefined selector is sent to your objects. There, you could check if you have an instance variable named according to the message, and return / change it if it is the case. Otherwise you just do super doesNotUnderstand: aMessage.
Regarding your comment: Classes are objects, too, so you don't have to do anything special to use them as parameters. On which class you add it is totally up to you and doesn't really matter. So a method to add instance variables could look like this:
addVariablesNamed: aCollection on: aClass
aCollection do: [:each | aClass addInstVarName: each]
and you could call it like this:
yourObject addVariablesNamed: #('foo' 'bar' 'baz') on: ClassX
You can find examples on how to generate accessor methods in the class CreateAccessorsForVariableRefactoring

In Squeak, open a Browser on the class. If you "right click" (I can never remember the button colours) the class name in the class list you'll get the standard context menu - "browse full (b)", and so on. Select "more..." and you'll see "create inst var accessors". Select that, and you'll get basic getters and setters for the instance variables.

Related

Intersystems caché - programmatically create new class

Is it possible to write ObjectScript method, which will create new class in namespace and compile it? I mean programmatically create new class and store it. If so, can I edit this class using ObjectScript later(and recompile)?
Reason: I have class structure defined in string variable and I need to add new class to namespace according this string.
Nothing is impossible. Everything in Caché can be created programmatically. And, Classes is not a execution. There are at least two ways to do it:
simple SQL Query CREATE TABLE, will create a class.
and as you already mentioned ObjectScript Code, which can do this.
All of definition of any classes defined in other classes. Which you can find in package %Dictionary.
The class itself defined in %Dictionary.ClassDefinition. Which have some properties, for defining any parts of classes. So, this is a simple code which create some class, with one property.
set clsDef=##class(%Dictionary.ClassDefinition).%New()
set clsDef.Name="package.classname"
set clsDef.Super="%Persistent"
set propDef=##class(%Dictionary.PropertyDefinition).%New()
set propDef.Name="SomeProperty"
set propDef.Type="%String"
do clsDef.Properties.Insert(propDef)
do clsDef.%Save()
And in latest versions, there is one more way for create/change class. If you have text of class as you can see it in Studio. Then, you can load it in Caché, with class %Compiler.UDL.TextServices
Yes, it is. You likely want to make use of %Dictionary.ClassDefinition and the related %Dictionary.*Definition classes (especially %Dictionary.PropertyDefinition, %Dictionary.MethodDefinition and %Dictionary.IndexDefinition) to create and/or modify your class. Provided your string contains some reasonable representation of the data, you should be able to create the class this way.
The actual class documentation is available at http://docs.intersystems.com/cache20141/csp/documatic/%25CSP.Documatic.cls?CLASSNAME=%25Dictionary.ClassDefinition
You can then compile the class by calling $system.OBJ.Compile("YourPackage.YourClass","ck").
(Note: If your string contains the exported XML definition of the class, you could also write the XML representation to a stream and then call $system.OBJ.LoadStream() to import the XML definition. I would only recommend this if you have an exported class definition to start with.)

Intersystems Cache - Correct syntax for %ListOfObjects

The documentation says this is allowed:
ClassMethod GetContacts() As %ListOfObjects(ELEMENTTYPE="ContactDB.Contact")
[WebMethod]
I want to do this:
Property Permissions As %ListOfObjects(ELEMENTTYPE="MyPackage.MyClass");
I get an error:
ERROR #5480: Property parameter not declared:
MyPackage.Myclass:ELEMENTTYPE
So, do I really have to create a new class and set the ELEMENTTYPE parameter in it for each list I need?
Correct syntax for %ListOfObjects in properties is this one
Property Permissions As list of MyPackage.MyClass;
Yes, a property does sometimes work differently than a method when it comes to types. That is an issue here, in that you can set a class parameter of the return value of a method declaration in a straightforward way, but that doesn't always work for class parameters on the class of a property.
I don't think the way it does work is documented completely, but here are some of my observations:
You can put in class parameters on a property if the type of the property is a data-type (which are often treated differently than objects).
If you look at the %XML.Adaptor class it has the keyword assignment statement
PropertyClass = %XML.PropertyParameters
This appears to add its parameters to all the properties of the class that declares it as its PropertyClass. This appears to be an example of Intersystems wanting to implement something (an XML adaptor) and realizing the implementation of objects didn't provide it cleanly, so they hacked something new into the class compiler. I can't really find much documentation so it isn't clear if its considered a usable API or an implementation detail subject to breakage.
You might be able to hack something this way - I've never tried anything similar.
A possibly simpler work around might be to initialize the Permissions property in %OnNew and %OnOpen. You will probably want a zero element array at that point anyway, rather than a null.
If you look at the implementation of %ListOfObjects you can see that the class parameter which you are trying to set simply provides a default value for the ElementType property. So after you create an instance of %ListOfObjects you could just set it's ElementType property to the proper element type.
This is a bit annoying, because you have to remember to do it every time by hand, and you might forget. Or a maintainer down the road might not now to do it.
You might hope to maybe make it a little less annoying by creating a generator method that initializes all your properties that need it. This would be easy if Intersystems had some decent system of annotating properties with arbitrary values (so you could know what ElementType to use for each property). But they don't, so you would have to do something like roll your own annotations using an XData block or a class method. This probably isn't worth it unless you have more use cases for annotations than just this one, so I would just do it by hand until that happens, if it ever does.

How can I access a method of the consumer class inside a method created at runtime in a method of the parameterized role using Moose with Perl?

I define a method inside a parametrized role that needs to create a new class at run time
using Moose::Meta::Class->create and apply that exact parametrized role to it. I am also making a new method for that role using
$new_class->meta->add_method( some_name => sub {
my ($self) = #_;
...
})
inside the sub {...} I want to access a method of the consumer class and use it for something, I have tried using $self->get_method, it didn't work, how do I do this?
Please notice that the $self inside the sub above is MooseX::Role::Parameterized::Meta::Role::Parameterizable
I also have another question, if I do this:
my $object = Moose::Meta::Class->create(
"some_type",
);
Why isn't $object of type some_type and it's some ugly MooseX::Role::Parameterized::Meta::Role::Parameterizable and how do I get to the object of type some_type?
To answer your second question, the reason is because Perl's OO doesn't allow you to add a method to just one instance of a class, so Moose has to fake it by creating a subclass with the extra method and reblessing the unique object into that subclass.
Note that, if you are doing things correctly and doing your introspection with isa, has, and/or does rather than by trying to rely on the name of the object's blessed package, this doesn't matter. The object still isa some_type, has all of some_type's attributes, and does all of some_type's roles even though it's now blessed into a package with an ugly auto-generated name.
It sounds like your underlying problem is nearly exactly what I described at this question: from within the role definition, you need to get at the class (and its meta-class) of the object or class the role is being applied to. This isn't possible from within normal roles, but it's possible through parameterized roles.
I'm not quite sure what you're trying to do here. Let's assume you have
my $new_class = Moose::Meta::Class->create('FooBar');
then $new_class is the meta object for FooBar. So, if you want to add a method to FooBar you would say
$new_class->add_method(foo => sub { … });
which would basically be the same as
FooBar->meta->add_method(foo => sub { … });
You should also probably use find_meta() from Moose::Util. This will return the correct meta object (if there is one) even if your class doesn't have a meta method or it uses it for something else.
As said, I'm not sure this answers your question.

How do you set the class of an object to something else?

I've seen this recently and now I can't find it …
How do you set the class of an object to something else?
--Update: Well, in Pharo! Like:
d:=Object new. d setClass: Dictionary.
Only that it isn't actually setClass. How can you modify the class pointer of an object?
There is #primitiveChangeClassTo:.
It requires that both original and target class have the same class layout. For some strange reason it expects an instance of the target class as parameter, which is however not used.
So you would do
d := Object new.
d primitiveChangeClassTo: Dictionary new.
however this fails, since dictionaries have two instance variables but plain objects have none.
If you are into meta-programming, you might also be interesting in using any object as a class. I used that in Protalk to realize a prototype based language that works directly on top of Smalltalk.
The method #setClass: is used in some specific contexts and with different implementations (Check it with the Method Finder).
Object has some helpers to conver the current object in other sort of, as for example #asOrderedCollection, because this last permit the operation:
asOrderedCollection
"Answer an OrderedCollection with the receiver as its only element."
^ OrderedCollection with: self
HTH.
ok, then you can try something as:
d := Object new.
e := Dictionary new.
d become: e.
But, please, try #become: with caution, because in lot of situations it break the image.
Take a look at Class ClassBuilder. It creates the a new class, when you modify a class, and then switches the instances of the former to instances of the later. Therefor it should provide some method that does, what you ask for.

How do I use classes?

I'm fairly new to programming, and there's one thing I'm confused by. What is a class, and how do I use one? I understand a little bit, but I can't seem to find a full answer.
By the way, if this is language-specific, then I'm programming in PHP.
Edit: There's something else I forgot to say. Specifically, I meant to ask how defining functions are used in classes. I've seen examples of PHP code where functions are defined inside classes, but I can't really understand why.
To be as succinct as possible: a class describes a collection of data that can perform actions on itself.
For example, you might have a class that represents an image. An object of this class would contain all of the data necessary to describe the image, and then would also contain methods like rotate, resize, crop, etc. It would also have methods that you could use to ask the object about its own properties, like getColorPalette, or getWidth. This as opposed to being able to directly access the color pallette or width in a raw (non-object) data collection - by having data access go through class methods, the object can enforce constraints that maintain consistency (e.g. you shouldn't be able to change the width variable without actually changing the image data to be that width).
This is how object-oriented programming differs from procedural programming. In procedural programming, you have data and you have functions. The functions act on data, but there's no "ownership" of the data, and no fundamental connection between the data and the functions which make use of it.
In object-oriented programming, you have objects which are data in combination with actions. Each type of data has a defined set of actions that it can perform on itself, and a defined set of properties that it allows functions and other objects to read and write in a defined, constraint-respecting manner.
The point is to decouple parts of the program from each other. With an Image class, you can be assured that all of the code that manipulates the image data is within the Image class's methods. You can be sure that no other code is going to be mucking about with the internals of your images in unexpected ways. On the other hand, code outside your image class can know that there is a defined way to manipulate images (resize, crop, rotate methods, etc), and not have to worry about exactly how the image data is stored, or how the image functions are implemented.
Edit: And one more thing that is sometimes hard to grasp is the relationship between the terms "class" and "object". A "class" is a description of how to create a particular type of "object". An Image class would describe what variables are necessary to store image data, and give the implementation code for all of the Image methods. An Image object, called an "instance" of an image class, is a particular use of that description to store some actual data. For example, if you have five images to represent, you would have five different image "objects", all of the same Image "class".
Classes is a term used in the object oriented programming (OOP) paradigm. They provide abstraction, modularity and much more to your code. OOP is not language specific, other examples of languages supporting it are C++ and Java.
I suggest youtube to get an understanding of the basics. For instance this video and other related lectures.
Since you are using PHP I'll use it in my code examples but most everything should apply.
OOP treats everything as an object, which is a collection of methods (functions) and variables. In most languages objects are represented in code as classes.
Take the following code:
class person
{
$gender = null;
$weight = null;
$height = null;
$age = null;
$firstName = null;
$lastName = null;
function __CONSTRUCT($firstName, $lastName)
{
//__CONSTRUCT is a special method that is called when the class is initialized
$this->firstName = $firstName;
$this->lastName = $lastName;
}
}
This is a valid (if not perfect) class when you use this code you'll first have to initailize an instance of the class which is like making of copy of it in a variable:
$steve = new person('Steve', 'Jobs');
Then when you want to change some property (not technicaly the correct word as there are no properties in PHP but just bear with me in this case I mean variable). We can access them like so:
$steve->age = 54;
Note: this assumes you are a little familiar with programming, which I guess you are.
A class is like a blueprint. Let's suppose you're making a game with houses in it. You'd have a "House" class. This class describes the house and says what can it do and what can be done to it. You can have attributes, like height, width, number of rooms, city where it is located, etc. You can also have "methods" (fancy name for functions inside a class). For example, you can have a "Clean()" method, which would tell all the people inside the house to clean it.
Now suppose someone is playing your game and clicks the "make new house" button. You would then create a new object from that class. In PHP, you'd write "$house = new House;", and now $house has all the attributes and methods of a class.
You can make as many houses as you want, and they will all have the same properties, which you can then change. For example, if the people living in a house decide to add one more room, you could write "$house->numberOfRooms++;". If the default number of rooms for a house was 4, this house would have 5 rooms, and all the others would have 4. As you can see, the attributes are independent from one instance to another.
This is the basics; there is a lot more stuff about classes, like inheritance, access modifiers, etc.
Now, you may ask yourself why is this useful. Well, the point of Object Oriented Programming (OOP) is to think of all the things in the program as independent objects, trying to design them so they can be used regardless of context. For example, your house may be a standalone variable, may be inside an array of houses. If you have a "Person" class with a "residence" attribute, then your house may be that attribute.
This is the theory behind classes and objects. I suggest you look around for examples of code. If you want, you can look at the classes I made for a Pong game I programmed. It's written in Python and may use some stuff you don't understand, but you will get the basic idea. The classes are here.
A class is essentially an abstraction.
You have built-in datatypes such as "int" or "string" or "float", each of which have certain behavior, and operations that are possible.
For example, you can take the square root of a float, but not of a string. You can concatenate two strings, or you can add two integers. Each of these data types represent a general concept (integers, text or numbers with a fixed number of significant digits, which may or may not be fractional)
A class is simply a user-defined datatype that can represent some other concept, including the operations that are legal on it.
For example, we could define a "password" class which implements the behavior expected of a password. That is, we should be able to take a text string and create a password from it. (If I type 'secret02', that is a legal password). It should probably perform some verification on this input string, making sure that it is at least N characters long, and perhaps that it is not a dictionary word. And it should not allow us to read the password. (A password is usually represented as ****** on the screen). Instead, it should simply allow us to compare the password to other passwords, to see if it is identical.
If the password I just typed is the same as the one I originally signed up with, I should be allowed to log in. But what the password actually is, is not something the application I'm logging in to should know. So our password class should define a comparison function, but not a "display" function.
A class basically holds some data, and defines which operations are legal on that data. It creates an abstraction.
In the password example, the data is obviously just a text string internally, but the class allows only a few operations on this data. It prevents us from using the password as a string, and instead only allows the specific operations that would make sense for a password.
In most languages, the members of a class can be either private or public. Anything that is private can only be accessed by other members of the class. That is how we would implement the string stored inside the password class. It is private, so it is still visible to the operations we define in the class, but code outside the class can not just access the string inside a password. They can only access the public members of the class.
A class is a form of structure you could think of, such as int, string and so forth that an instance can be made from using object oriented programming language. Like a template or blueprint the class takes on the structure. You write this structure with every association to the class. Something from a class would be used as an object instance in the Main() method where all the sysync programming steps take place.
This is why you see people write code like Car car = new Car();to draw out a new object from a class. I personally do not like this type of code, its very bad and circular and does not explain which part is the class syntax (arrangement). Too bad many programmers use this syntax and it is difficult for beginners to understand what they are perceiving.
Think of this as,
CarClass theCar = new CarClass(); //
The class essentially takes on the infinitely many forms. You can write properties that describe the CarClass and every car generated will have these. To get them from the property that "gets" what (reads) and "sets" what (writes) data, you simply use the dot operator on the object instance generates in the Main() and state the descriptive property to the actual noun. The class is the noumenon (a word for something like math and numbers, you cannot perceive it to the senses but its a thought like the #1). Instead of writing each item as a variable the class enables us to write a definition of the object to use.
With the ability to write infinitely many things there is great responsibility! Like "Hello World!" how this little first statement says much about our audience as programmers.
So
CarClass theCar = new CarClass(); //In a way this says this word "car" will be a car
theCar.Color = red; //Given the instance of a car we can add that color detail.
Now these are only implementations of the CarClass, not how to build one.
You must be wondering what are some other terms, a field, constructor, and class level methods and why we use them and indexing.
A field is another modifier on a property. These tend to be written on a private class level so nothing from the outside affects it and tends to be focused on the property itself for functionality. It is in another region where you declare it usually with an underscore in front of it. The field will add constraints necessary to maintain data integrity meaning that you will prevent people from writing values that make no sense in the context. (Like real like measurements in the negative... that is just not real.)
The Constructor
The easiest way to describe a constructor is to make claims to some default values on the object properties where the constructor scope is laid. In example a car has a color, a max speed, a model and a company. But what should these values be and should some be used in millions of copies from the CarClass or just a few? The constructor enables one to do this, to generate copies by establishing a basic quality. These values are the defaults assigned to a property in a constructor block. To design a constructor block type ctor[tab][tab]. Inside this simply refer to those properties you write above and place an assigned value on it.
Color = “Red”;
If you go to the main() and now use the car.Color property in any writing output component such as a the console window or textbox you should see the word “Red”. The details are thus implicit and hidden. Instead of offering every word from a book you simply refer to the book then the computer gets the remaining information. This makes code scripts compact and easy to use.
The Class level method should explain how to do some process over and over. Typically a string or some writing you can format some written information for a class and format it with placeholders that are in the writing to display that are represented with your class properties. It makes sense when you make an object instance then need to use the object to display the details in a .ToString() form. The class object instance in a sense can also contain information like a book or box. When we write .ToString() with a ToString override method at class level it will print your custom ToString method and how it should explain the code. You can also write a property .ToString() and read it. This below being a string should read fine as it is...
Console.Writeline(theCar.Color);
Once you get many objects, one at a time you can put them in a list that allows you to add or remove them. Just wait...
Here's a good page about Classes and Objects:
http://ficl.sourceforge.net/oo_in_c.html
This is a resource which I would kindly recommend
http://www.cplusplus.com/doc/tutorial/
not sure why, but starting with C++ to apply OOP might be natural prior of any other language, the above link helped me a lot when I started at least.
Classes are a way programmers mark their territory on code.
They are supposedly necessary for writing big projects.
Linus and his team must have missed that memo developing the linux kernel.
However, they can be good for organization and categorizing code I guess.
It makes it easier to navigate code in an ide such as visual studio with the object browsers.
Here are some usage demonstrations of classes in 31 languages on rosettacode
First of all back to the definitions:
Class definition:
Abstract definition of something, an user-type, a blueprint;
Has States / Fields / Properties (what an object knows) and Methods / Behaviors / Member Functions (what an object does);
Defines objects behavior and default values;
Object definition:
Instance of a Class, Repository of data;
Has a unique identity: the property of an object that distinguishes it from other objects;
Has its own states: describes the data stored in the object;
Exhibits some well defined behavior: follows the class’s description;
Instantiation:
Is the way of instantiate a class to create an object;
Leaves the object in a valid state;
Performed by a constructor;
To use a class you must instantiate the class though a contructor. In PHP a straight-forward example could be:
<?php
class SampleClass {
function __construct() {
print "In SampleClass constructor\n";
}
}
// In SampleClass constructor
$obj = new SampleClass ();
?>