create vs new in object creation with TclOO - tcl

I am looking into TclOO and found that we can use create or new for object creation.
With create we can provide customized name, whereas with new, it is computer generated.
#!/bin/bash
#\
exec tclsh8.6 $0 $#
::oo::class create calc {
method add { a b } {
return [ expr {$a+$b} ]
}
}
calc create c;
set t [ calc new ]
# Both serves the same purpose here
puts [ c add 3 4 ]
puts [ $t add 1 2 ]
Is it only about object naming convenience provided by compiler to developer? Also, what can be the scenario where I should prefer new instead of create ?

The only difference between new and create is exactly that create lets you give the name to use, and new makes a fresh one for you. Some kinds of objects (specifically classes) conceal their new method so that you are strongly encouraged to only make named instances — given how people use classes, that makes a lot of sense in practice — but it's just concealment and you can override that if you want:
oo::define oo::class {
export new
}
Use new when you don't care about the name and just want it to be different from everything else. That's the basic rule-of-thumb.
Singletons
It's also perfect to use create to make instances where other OO systems might use singletons. What's more unique than giving them a nice unique name that you control.
Lifespan management
The main scenario I'm aware of otherwise where using create is much more useful is when you want to bound the lifespan of an object to another. In that case, creating the object within the context of another will put the object handle in the container's namespace, and will automatically trigger a delete on the deletion of the container:
oo::class create InsideThing {
constructor {} {
puts "Made a [self] that is an InsideThing"
}
destructor {
puts "Deleted a [self] that is an InsideThing"
}
}
oo::class create Container {
constructor {} {
puts "Created a [self] that is a Container"
InsideThing create inner1
InsideThing create inner2
}
destructor {
puts "Deleted a [self] that is a Container"
}
}
set c [Container new]
puts "Do stuff..."
$c destroy
If you run that code, you get this:
Created a ::oo::Obj13 that is a Container
Made a ::oo::Obj13::inner1 that is an InsideThing
Made a ::oo::Obj13::inner2 that is an InsideThing
Do stuff...
Deleted a ::oo::Obj13 that is a Container
Deleted a ::oo::Obj13::inner1 that is an InsideThing
Deleted a ::oo::Obj13::inner2 that is an InsideThing
This technique is widely used in TDBC to manage result sets and statements within the context of their containers (statements and connections, respectively).
Tk Megawidgets
Finally, if you are creating Tk megawidgets using TclOO, you will definitely be using create but in overridden form, as Tk widgets must have unqualified names that start with a . and which have a specific embodied hierarchy, and megawidgets are very strongly advised to follow the same pattern. Because the name matters a lot in this situation, new is the wrong method; it is better to start from create. Tk 8.6 has some support classes (not publicly described, but used internally for some dialogs) that makes this sort of thing easier: tk::Megawidget and tk::MegawidgetClass. Check out megawidget.tcl in a Tk 8.6 distribution for details.

Related

Tcl: Difference between different ways of adding instance class

I found two ways to instance class:
one is:
class_name create instance
instance class_method
the other is:
set instance [class_name new]
$instance class_method
Each way worked well, so is there any difference between two ways?
The only difference is that the new method on classes generates a unique name for you, and with the create method you get to specify what the name is. Both are provided because there's use cases for each of them. Use whichever makes sense for you. (Note that class objects themselves are always named because of how they're generally used, and so you can't normally create classes with new; it's hidden on oo::class instances.)
For the sake of completeness only, there's an additional way to make instances, createWithNamespace, which lets you also specify the name of the state namespace of the object. It's not exposed by default (you have to manually export it for general use) and is pretty specialist for people who aren't doing deep shenanigans. You probably don't want to use it.
At some point in the future new may be enhanced so that it also enables garbage collection for the object, whereas create will not (because you know the name out-of-band). Specifically, I've written a TIP for doing this for Tcl 9.0 but I don't have a working implementation yet, so do not hold your breath.
I have tried some cases,
class defined as this:
oo::class create class_name {
variable text
method add {t} { set text $t }
method print { } { puts $text }
}
First way:
class_name create foo
foo add "abc"
foo print
class_name create foo
It will return:
abc
Error: can't create object "foo": command already exists with that name
Second way:
set foo [class_name new]
$foo add "abc"
$foo print
set foo [class_name new]
$foo add "def"
$foo print
It will return:
abc
def
This is one difference I found, and it seems like secnod way is more convenient.
Still expecting master to provide authoritative answers or documents.

Copy Command's Parameters Dynamically

Is there a way to copy the parameters from one function, to the my current function 'dynamically'?
Ex:
Function CopyVerify-Item {
DynamicParam {
# Get all the parameters from Copy-Item
}
Process {
Copy-Item $PSBoundParameters
# Do my extra code here to verify the copy
}
}
I need it to be an exact copy, with switches, mandatory, ParameterSets..
I want to use this new function, exactly like the original one, except include extra code in the function.
** This is a stupid/pure example of what i'm doing, but in reality, it's a lot more complex.. and don't want to have to replicate all my
parameters each time for each function.. and some functions are
created dynamically as well.. so i'm just keeping the example VERY
simple.
AFAIK functions doesn't support inhertiance. You need to copy/paste the common parameters/code.
If you're comfortable with C# you could create cmdlets in a binary module using. Then you could use an abstract class for your common parameters. You might have to create simple override-"wrappers" for the properties to include them in ParameterSets though.
Ex.
public abstract class FrodeCommandBase : PSCmdlet
{
#properties, getters setters etc.
}
public class GetFrodeCommand: FrodeCommandBase
{
}
You might have to create simple override-"wrappers" for the properties to include them in ParameterSets though.

How can I declare an adjustable number of variables in the constructor of TclOO object which are visible in other methods?

This is somewhat similar to this question TclOO Variable Scope with Inheritance/superclass,
but I would like to make a number of variables available to the methods in my class, and which ones and how many those are is determined dynamically at runtime.
Pseudocode:
oo::class create myClass {
constructor {registryObject} {
foreach variable [$registryObject getVariables] {
<make $variable visible to all methods>
}
method useVariable{} {
<do something with previously declared variable>
}
}
is there any way to achieve this without another layer of indirection? The problem is that the registryObject gives me a variable number of references to other objects, which I would like to be accessible in derived classes. As with the question referenced above, the point here is brevity in the code of a derived class. I am willing to use dirty and complicated hacks in the superclass if neccessary.
It's going to be really hard to do exactly what you're asking for.
The variable class declaration used in TclOO adjusts how Tcl resolves variables in (normal class-defined) methods declared in the same class. It does not affect methods defined by superclasses, subclasses or instances (which should use their own variable declarations if they want them). The variables themselves are visible though — all variables associated with an instance are variables in the current namespace while the object is executing (which is instance-specific) — they just have to be brought in explicitly.
If the response to the registry object query was being used to dynamically create instance methods, you could do it:
constructor {registryObject} {
foreach variable [$registryObject getVariables] {
oo::objdefine [self] variable $variable
}
oo::objdefine [self] method foo {...} {
# This method *will* have automatic access
}
}
Yes, the method is created inside the constructor (and it doesn't make much sense to create the methods on the class). No, most other object systems don't have instance methods. Think of it as being a bit like giving each instance its own special little class. (That's not what happens, but it's not too far off.)
What you were asking to do
If you were going to create the methods for all instances of the class, it makes sense to do so either during the creation of the class (boring, conventional!) or during the creation of the first instance of the class, assuming the registry does the sensible thing and gives the same answer for all instances of that class. If that's the case, you could do it. Overriding the create and new methods is probably the simplest way to do it:
oo::class create myClass {
self method create {name registryObject} {
foreach var [$registryObject getVariables] {
oo::define [self] variable $var
}
next $name $registryObject
}
self method new {registryObject} {
foreach var [$registryObject getVariables] {
oo::define [self] variable $var
}
next $registryObject
}
constructor ...
method ...
}
It's a bit slow to do it this way because each object creation will trigger recompilation of lots of things, but it ought to work.
Or you could do it in the constructor; I think it's less elegant but you might disagree:
constructor {registryObject} {
oo::define [self class] variable {*}[$registryObject getVariables]
}
I think both of these options are not good ways to do it and I recommend doing the registry lookup during class creation. Or making the methods not rely on the variable mechanism, instead using my variable (very much like global but for instance variables) to access the variables they need.
If only I could figure out more exactly what the bigger picture was, I could help you better…

Adding help to the user defined functions in TCL

how can i add some kind of help to the user defined functions in TCL
Supposing if i have a function called runtest {ip_address test_time},
How to describe what the test or procedure is about in the TCL_shell?
How can i specify the information to the user, if he types in function_name --help in the TCL shell the user should be able to know what the function does and what exactly are the parameters.
how can i do this?
While it is true that it is not part of the language, it is fairly easy to implement something that adds this functionality to pre-existing functions. The only caveat being that the function then cannot take the string --help as a valid argument since that argument will trigger the feature.
Here's one simple implementation:
# Lets call the feature "document". As in, add documentation:
proc document {procname text} {
rename $procname __$procname
proc $procname args [string map [list %TEXT% $text %PROC% $procname] {
if {$args == "--help"} {
puts {%TEXT%}
} else {
set script [linsert $args 0 __%PROC%]
return [uplevel 1 $script]
}
}]
}
What this does is to override the function (by renaming and then declaring another function of the same name) and see if the function is called with the argument --help. If it is it prints the documentation otherwise it executes the original function. Just be careful not to call this twice on the same function (it can be modified for it to work though).
So you can do things like:
proc foo {} {puts 2}
document foo {Prints the number 2.}
Now if you call:
foo --help
and it would output:
Prints the number 2.
You don't have to touch the existing procedures:
proc help {procname} {
puts $::helptext($procname)
}
proc addhelp {procname text} {
set ::helptext($procname) $text
}
addhelp foo "this is the help text for procedure foo"
help foo
Without redefining the proc command, you cannot. Ie, that functionality is not built into the language, but would be possible to add if you so wished.
I will note that adding the capability yourself, while possible, is probably beyond the difficulty where it's worth doing, especially for someone that isn't intimately familiar with the language. That being said, you can check the tclers wiki for a preexisting implementation.
I tend to prefer to put help in a separate file (e.g., as HTML) which lets me browse it in another window. There are so many ways you can do that while still keeping the docs with the code, such as through doxygen.
There are also a number of ways of doing interactive documentation, several of which are described in the Tcler's Wiki; it would seem to me that some of the techniques mentioned on that page (together with #slebetman's answer) would give you what you wanted. (I think it would be easier to have a separate help command as that would avoid having the help syntax interfere with the command, but that's your call.)

Which design is better for a class that simply runs a self-contained computation?

I'm currently working on a class that calculates the difference between two objects. I'm trying to decide what the best design for this class would be. I see two options:
1) Single-use class instance. Takes the objects to diff in the constructor and calculates the diff for that.
public class MyObjDiffer {
public MyObjDiffer(MyObj o1, MyObj o2) {
// Calculate diff here and store results in member variables
}
public boolean areObjectsDifferent() {
// ...
}
public Vector getOnlyInObj1() {
// ...
}
public Vector getOnlyInObj2() {
// ...
}
// ...
}
2) Re-usable class instance. Constructor takes no arguments. Has a "calculateDiff()" method that takes the objects to diff, and returns the results.
public class MyObjDiffer {
public MyObjDiffer() { }
public DiffResults getResults(MyObj o1, MyObj o2) {
// calculate and return the results. Nothing is stored in this class's members.
}
}
public class DiffResults {
public boolean areObjectsDifferent() {
// ...
}
public Vector getOnlyInObj1() {
// ...
}
public Vector getOnlyInObj2() {
// ...
}
}
The diffing will be fairly complex (details don't matter for the question), so there will need to be a number of helper functions. If I take solution 1 then I can store the data in member variables and don't have to pass everything around. It's slightly more compact, as everything is handled within a single class.
However, conceptually, it seems weird that a "Differ" would be specific to a certain set of results. Option 2 splits the results from the logic that actually calculates them.
EDIT: Option 2 also provides the ability to make the "MyObjDiffer" class static. Thanks kitsune, I forgot to mention that.
I'm having trouble seeing any significant pro or con to either option. I figure this kind of thing (a class that just handles some one-shot calculation) has to come up fairly often, and maybe I'm missing something. So, I figured I'd pose the question to the cloud. Are there significant pros or cons to one or the other option here? Is one inherently better? Does it matter?
I am doing this in Java, so there might be some restrictions on the possibilities, but the overall question of design is probably language-agnostic.
Use Object-Oriented Programming
Use option 2, but do not make it static.
The Strategy Pattern
This way, an instance MyObjDiffer can be passed to anyone that needs a Strategy for computing the difference between objects.
If, down the road, you find that different rules are used for computation in different contexts, you can create a new strategy to suit. With your code as it stands, you'd extend MyObjDiffer and override its methods, which is certainly workable. A better approach would be to define an interface, and have MyObjDiffer as one implementation.
Any decent refactoring tool will be able to "extract an interface" from MyObjDiffer and replace references to that type with the interface type at some later time if you want to delay the decision. Using "Option 2" with instance methods, rather than class procedures, gives you that flexibility.
Configure an Instance
Even if you never need to write a new comparison method, you might find that specifying options to tailor the behavior of your basic method is useful. If you think about using the "diff" command to compare text files, you'll remember how many different options there are: whitespace- and case-sensitivity, output options, etc. The best analog to this in OO programming is to consider each diff process as an object, with options set as properties on that object.
You want solution #2 for a number of reasons. And you don't want it to be static.
While static seems like fun, it's a maintenance nightmare when you come up with either (a) a new algorithm with the same requirements, or (b) new requirements.
A first-class object (without much internal state) allows you to evolve into a class hierarchy of different differs -- some slower, some faster, some with more memory, some with less memory, some for old requirements, some for new requirements.
Some of your differs may wind up with complicated internal state or memory, or incremental diffing or hash-code-based diffing. All kinds of possibilities might exist.
A reusable object allows you to pick your differ at application start-up time using a properties file.
In the long run, you want to minimize the number of new operations that are scattered throughout your application. You'd like to have your new operations focused in places where you can find and control them. To change from old differ algorithm to new differ algorithm, you'd like to do the following.
Write the new subclass.
Update a properties file to start using the new subclass.
And be completely confident that there wasn't some hidden d= new MyObjDiffer( x, y ) tucked away that you didn't know about.
You want to use d= theDiffer.getResults( x, y ) everywhere.
What the Java libraries do is they have a DifferFactory that's static. The factor checks the properties and emits the correct Differ.
DifferFactory df= new DifferFactory();
MyObjDiffer mod= df.getDiffer();
mod.getResults( x, y );
The Factory typically caches the single copy -- it doesn't have to physically read the properties every time getDiffer is called.
This design gives you ultimate flexibility in the future. At it looks like other parts of the Java libraries.
I can't really say I have firm reasons why it's the 'best' approach, but I usually write classes for objects that you can have a 'conversation' with. So it would be like your 'single use' option 1, except that by calling a setter, you would 'reset' it for another use.
Rather than supplying the implementation (which is pretty obvious), here's a sample invocation:
MyComparer cmp = new MyComparer(obj1, obj2);
boolean match = cmp.isMatch();
cmp.setSubjects(obj3,obj4);
List uniques1 = cmp.getOnlyIn(MyComparer.FIRST);
cmd.setSubject(MyComparer.SECOND,obj5);
List uniques = cmp.getOnlyIn(MyComparer.SECOND);
... and so on.
This way, the caller gets to decide whether they want to instantiate lots of objects, or keep reusing the one.
It's particularly useful if the object needs a lot of setup. Lets say your comparer takes options. There could be many. Set it up once, then use it many times.
// set up cmp with options and the master object
MyComparer cmp = new MyComparer();
cmp.setIgnoreCase(true);
cmp.setIgnoreTrailingWhitespace(false);
cmp.setSubject(MyComparer.FIRST,canonicalSubject);
// find items that are in the testSubjects objects,
// but not in the master.
List extraItems = new ArrayList();
for (Iterator it=testSubjects.iterator(); it.hasNext(); ) {
cmp.setSubject(MyComparer.SECOND,it.next());
extraItems.append(cmp.getOnlyIn(MyComparer.SECOND);
}
Edit: BTW I called it MyComparer rather than MyDiffer because it seemed more natural to have an isMatch() method than an isDifferent() method.
I'd take numero 2 and reflect on whether I should make this static.
Why are you writing a class whose only purpose is to calculate the difference between two objects? That sounds like a task either for a static function or a member function of the class.
I would go for a static constructor method, something like.
Diffs diffs = Diffs.calculateDifferences(foo, bar);
In this way, it's clear when you're calculating the differences, and there is no way to misuse the object's interface.
I like the idea of explicitly starting the work rather than having it occur on instantiation. Also, I think the results are substantial enough to warrant their own class. Your first design isn't as clean to me. Someone using this class would have to understand that after performing the calculation some other class members are now holding the results. Option 2 is more clear about what is happening.
It depends on how you're going to use diffs. In my mind, it makes sense to treat diffs as a logical entity because it needs to support some operations like 'getDiffString()', or 'numHunks()', or 'apply()'. I might take your first one and do it more like this:
public class Diff
{
public Diff(String path1, String path2)
{
// get diff
if (same)
throw new EmptyDiffException();
}
public String getDiffString()
{
}
public int numHunks()
{
}
public bool apply(String path1)
{
// try to apply diff as patch to file at path1. Return
// whether the patch applied successfully or not.
}
public bool merge(Diff diff)
{
// similar to apply(), but do merge yourself with another diff
}
}
Using a diff object like this also might lend itself to things like keeping a stack of patches, or serializing to a compressed archive, maybe an "undo" queue, and so on.