create a class object as variable in Tcloo - oop

I start to use tclOO.
I need to create a Aclass instance anotherClassIns in my main class MainClass as below:
oo:class create Aclass {
variable num;
constructor {argv} {
set num [lindex $argv 0]
}
}; #end of Aclass
oo:class create MainClass {
variable anotherClassIns ; # this variable is another class's instance!
constructor {argv} {
Aclass create anotherClassIns {$argv};
}
}
And in main function, I create a MainClass instance:
MainClass create Ins $argv
If I want to print $num in Aclass, how can I do?
Thanks.

All instance variables in TclOO have globally-addressable names so that they can be used with other parts of Tcl that expect such (especially vwait and trace, but also Tk's -textvariable options).
The easiest way for now is to make an accessor method:
oo:class create Aclass {
variable num
constructor {argv} {
set num [lindex $argv 0]
}
method num {} {
return $num
}
}
oo:class create MainClass {
variable anotherClassIns
constructor {argv} {
set anotherClassIns [Aclass new {*}$argv]
}
destructor {} {
# Assuming you're owning the inner instance
$anotherClassIns destroy
}
method printTheValue {} {
puts [$anotherClassIns num]
}
}
You can also access the variable directly by using the fact that variables exist in a namespace, and that namespace can be looked up with info object namespace:
method printTheValue {} {
# Probably easiest to do this
namespace upvar [info object namespace $anotherClassIns] num v
puts $v
}
But that won't work with 8.7's private variables, as those are name-mangled in a way that is decidedly non-accessible to outside code. In that case, you'd need to get Aclass to provide access into its internals; that's literally the point of private variables. The varname method of oo::object can help there; it's not exposed by default, but it's available internally via my, and you can expose it for a class or even just an instance via the export definition.
# Probably at object creation time
oo::objdefine $anotherClassIns export varname
# Then, to access
puts [set [$anotherClassIns varname num]]
# Or
upvar 0 [$anotherClassIns varname num] v
puts $v
There's a similar variable method, but that requires that you don't have a colliding local num variable:
# Object creation time
oo::objdefine $anotherClassIns export variable
# Access
$anotherClassIns variable num
puts $num

Related

proc in Tcl oo::class

A silly question. I have a oo::class and make an awful thing - including procs into a constructor and a method:
oo::class create MyClass {
constructor {args} {
proc silly {args} {
puts "-------------silly's args: $args"
puts namespace=[namespace current]
set v [namespace current]::sillyvar
puts $v=[incr $v]
puts vars=[info vars [namespace current]::*]
}
}
destructor {
foreach proc {silly SILLY} {
rename $proc ""
}
}
method createprocs {} {
proc SILLY {args} {
puts "-------------SILLY's args: $args"
set v [namespace current]::sillyvar
puts $v=[incr $v]
}
}
method another {} {
silly ;# works ok
}
}
MyClass create myobj
myobj createprocs
[info object namespace myobj]::silly hello world
myobj another
[info object namespace myobj]::SILLY HELLO WORLD
MyClass destroy
The output looks OK:
-------------silly's args: hello world
namespace=::oo::Obj12
::oo::Obj12::sillyvar=1
vars=::oo::Obj12::sillyvar
-------------silly's args:
namespace=::oo::Obj12
::oo::Obj12::sillyvar=2
vars=::oo::Obj12::sillyvar
-------------SILLY's args: HELLO WORLD
::oo::Obj12::sillyvar=3
Can you kind folks say, is it correct? And if so, where it can be useful?
What I see just now is:
1) The silly and the SILLY both are 'exported'.
2) I need no "my silly" and "[self] silly" to access the silly proc from an object.
Can you kind folks say, is it correct?
It looks OK to me, except that you don't need the destructor. The procedures are created in the object instance's namespace (which is also where the object's variables are, FWIW) and that's automatically deleted when the object is destroyed (and vice versa too; you can't have one without the other).
And if so, where it can be useful?
I use procedures (and other commands) created inside methods and constructors a fair bit. They can do things like acting like a private sub-language of Tcl and so on (just as you can do with putting commands in a normal namespace; it's not significantly different), so that's really quite useful. They're also very easy to delegate to using a forwarded method.
One of the easier tricks is to make a sub-object inside an outer object and to delegate some method calls through:
oo::class create Outer {
constructor {} {
Inner create inner [self]
puts "created [self]"
}
destructor {
puts "destroyed [self]"
}
method foo {} {
puts "this is foo of [self]"
}
forward bar inner foo
}
oo::class create Inner {
constructor {outer} {
puts "created [self] inside $outer"
}
destructor {
puts "destroyed [self]"
}
method foo {} {
puts "this is foo of [self]"
}
}
Demonstrating this:
Outer create x
# ⇒ created ::oo::Obj13::inner inside ::x
# ⇒ created ::x
x foo
# ⇒ this is foo of ::x
x bar
# ⇒ this is foo of ::oo::Obj13::inner
x destroy
# ⇒ destroyed ::x
# ⇒ destroyed ::oo::Obj13::inner
This shows the containment and delegation at work (which is based on the same mechanism that your procedures would be using). As you can see, inner is made inside the private namespace of x, and x bar is routed through to inner foo. Even better, when x is destroyed, so is inner with no special code at all; that's very useful in complex code.

PHP Static and Normal Functions Calling [duplicate]

There are two distinct ways to access methods in PHP, but what's the difference?
$response->setParameter('foo', 'bar');
and
sfConfig::set('foo', 'bar');
I'm assuming -> (dash with greater than sign or chevron) is used for functions for variables, and :: (double colons) is used for functions for classes. Correct?
Is the => assignment operator only used to assign data within an array? Is this in contrast to the = assignment operator which is used to instantiate or modify a variable?
When the left part is an object instance, you use ->. Otherwise, you use ::.
This means that -> is mostly used to access instance members (though it can also be used to access static members, such usage is discouraged), while :: is usually used to access static members (though in a few special cases, it's used to access instance members).
In general, :: is used for scope resolution, and it may have either a class name, parent, self, or (in PHP 5.3) static to its left. parent refers to the scope of the superclass of the class where it's used; self refers to the scope of the class where it's used; static refers to the "called scope" (see late static bindings).
The rule is that a call with :: is an instance call if and only if:
the target method is not declared as static and
there is a compatible object context at the time of the call, meaning these must be true:
the call is made from a context where $this exists and
the class of $this is either the class of the method being called or a subclass of it.
Example:
class A {
public function func_instance() {
echo "in ", __METHOD__, "\n";
}
public function callDynamic() {
echo "in ", __METHOD__, "\n";
B::dyn();
}
}
class B extends A {
public static $prop_static = 'B::$prop_static value';
public $prop_instance = 'B::$prop_instance value';
public function func_instance() {
echo "in ", __METHOD__, "\n";
/* this is one exception where :: is required to access an
* instance member.
* The super implementation of func_instance is being
* accessed here */
parent::func_instance();
A::func_instance(); //same as the statement above
}
public static function func_static() {
echo "in ", __METHOD__, "\n";
}
public function __call($name, $arguments) {
echo "in dynamic $name (__call)", "\n";
}
public static function __callStatic($name, $arguments) {
echo "in dynamic $name (__callStatic)", "\n";
}
}
echo 'B::$prop_static: ', B::$prop_static, "\n";
echo 'B::func_static(): ', B::func_static(), "\n";
$a = new A;
$b = new B;
echo '$b->prop_instance: ', $b->prop_instance, "\n";
//not recommended (static method called as instance method):
echo '$b->func_static(): ', $b->func_static(), "\n";
echo '$b->func_instance():', "\n", $b->func_instance(), "\n";
/* This is more tricky
* in the first case, a static call is made because $this is an
* instance of A, so B::dyn() is a method of an incompatible class
*/
echo '$a->dyn():', "\n", $a->callDynamic(), "\n";
/* in this case, an instance call is made because $this is an
* instance of B (despite the fact we are in a method of A), so
* B::dyn() is a method of a compatible class (namely, it's the
* same class as the object's)
*/
echo '$b->dyn():', "\n", $b->callDynamic(), "\n";
Output:
B::$prop_static: B::$prop_static value
B::func_static(): in B::func_static
$b->prop_instance: B::$prop_instance value
$b->func_static(): in B::func_static
$b->func_instance():
in B::func_instance
in A::func_instance
in A::func_instance
$a->dyn():
in A::callDynamic
in dynamic dyn (__callStatic)
$b->dyn():
in A::callDynamic
in dynamic dyn (__call)
:: is used in static context, ie. when some method or property is declared as static:
class Math {
public static function sin($angle) {
return ...;
}
}
$result = Math::sin(123);
Also, the :: operator (the Scope Resolution Operator, a.k.a Paamayim Nekudotayim) is used in dynamic context when you invoke a method/property of a parent class:
class Rectangle {
protected $x, $y;
public function __construct($x, $y) {
$this->x = $x;
$this->y = $y;
}
}
class Square extends Rectangle {
public function __construct($x) {
parent::__construct($x, $x);
}
}
-> is used in dynamic context, ie. when you deal with some instance of some class:
class Hello {
public function say() {
echo 'hello!';
}
}
$h = new Hello();
$h->say();
By the way: I don't think that using Symfony is a good idea when you don't have any OOP experience.
Actually by this symbol we can call a class method that is static and not be dependent on other initialization...
class Test {
public $name;
public function __construct() {
$this->name = 'Mrinmoy Ghoshal';
}
public static function doWrite($name) {
print 'Hello '.$name;
}
public function write() {
print $this->name;
}
}
Here the doWrite() function is not dependent on any other method or variable, and it is a static method. That's why we can call this method by this operator without initializing the object of this class.
Test::doWrite('Mrinmoy');
// Output: Hello Mrinmoy.
But if you want to call the write method in this way, it will generate an error because it is dependent on initialization.
The => operator is used to assign key-value pairs in an associative array. For example:
$fruits = array(
'Apple' => 'Red',
'Banana' => 'Yellow'
);
It's meaning is similar in the foreach statement:
foreach ($fruits as $fruit => $color)
echo "$fruit is $color in color.";
The difference between static and instantiated methods and properties seem to be one of the biggest obstacles to those just starting out with OOP PHP in PHP 5.
The double colon operator (which is called the Paamayim Nekudotayim from Hebrew - trivia) is used when calling an object or property from a static context. This means an instance of the object has not been created yet.
The arrow operator, conversely, calls methods or properties that from a reference of an instance of the object.
Static methods can be especially useful in object models that are linked to a database for create and delete methods, since you can set the return value to the inserted table id and then use the constructor to instantiate the object by the row id.
Yes, I just hit my first 'PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM'. My bad, I had a $instance::method() that should have been $instance->method(). Silly me.
The odd thing is that this still works just fine on my local machine (running PHP 5.3.8) - nothing, not even a warning with error_reporting = E_ALL - but not at all on the test server, there it just explodes with a syntax error and a white screen in the browser. Since PHP logging was turned off at the test machine, and the hosting company was too busy to turn it on, it was not too obvious.
So, word of warning: apparently, some PHP installations will let you use a $instance::method(), while others don't.
If anybody can expand on why that is, please do.

Can't hide constructor at [incr Tcl]

Consider the code below.
package require Itcl
::itcl::class A \
{
private {
constructor { } { } { puts "==== at A::constructor" }
method f { } { puts "==== at A::f" }
}
}
A a ;# PASSES
a f ;# fails
For class A the constructor is private, but it is still possible to define an object of A.
Am I doing something wrong, or incr Tcl is designed to behave so?
I believe this is the way itcl work, if you look at the specification for a class:
itcl::class className {
inherit baseClass ?baseClass...?
constructor args ?init? body
destructor body
method name ?args? ?body?
proc name ?args? ?body?
variable varName ?init? ?config?
common varName ?init?
public command ?arg arg ...?
protected command ?arg arg ...?
private command ?arg arg ...?
set varName ?value?
array option ?arg arg ...?
}
className objName ?arg arg ...?
objName method ?arg arg ...?
className::proc ?arg arg ...?
you can see that private/protected can be applied to command but not to the constrcutor or the destructor. Looking here at the documentation on the itcl design patterns may also give some clues as to how to achieve something close to a private constructor.

Static function inheritance in [incr Tcl]

Inheritance in incr Tcl doesn't work as expected. Consider the code below.
package require Itcl
::itcl::class Base \
{
public {
proc function { } { puts "==== Base::function" }
}
}
::itcl::class Derived { inherit Base }
Base::function
Derived::function ;# FAILS
The last line fails, so Base::function is not inherited at Derived, though Derived inherits from Base.
Am I doing something wrong, or incr Tcl is designed to behave so?
Reading the docs I don't think that procs in an itcl class work the way you think they ought to:
proc name ?args? ?body?
Declares a proc called name. A proc is an ordinary procedure within
the class namespace. Unlike a method,
a proc is invoked without referring to
a specific object. When the proc body
is executed, it will have automatic
access only to common data members.
If the args list is specified, it establishes the usage information for
this proc. The body command can be
used to redefine the proc body, but
the args list must match this
specification.
Within the body of another class method or proc, a proc can be invoked
like any other command-simply by using
its name. In any other namespace
context, the proc is invoked using a
qualified name like "className::proc".
Procs in a base class that are
redefined in the current class, or
hidden by another base class, can also
be accessed via their qualified name.
My reading of this is that the proc is associated with it's class, it can be referred to in the derived class but it isn't defined in it. For example the following works:
package require Itcl
::itcl::class Base {
public {
proc function { } { puts "==== Base::function" }
}
}
::itcl::class Derived {
inherit Base
public {
proc function { } {
puts "==== Derived::function"
return [Base::function]
}
}
}
Base::function
Derived::function ;# FAILS
The proc you defined Base::function is (more or less) a regular proc in the namespace Base. When you inherit in Itcl, you just inherit methods, you don't inherit procs. In a related note, you cannot call the proc function from an instance of Base, you have to call it like any regular proc.
itcl::class Base {
public {
proc function { } { puts "==== Base::function" }
}
public method test {} {
$this function
}
public method test2 {} {
function
}
}
Base bb
bb test ;# yields error: bad option "function"
bb test2 ;# works as expected

What is the difference between a member variable and a local variable?

What is the difference between a member variable and a local variable?
Are they the same?
A local variable is the variable you declare in a function.
A member variable is the variable you declare in a class definiton.
A member variable is a member of a type and belongs to that type's state. A local variable is not a member of a type and represents local storage rather than the state of an instance of a given type.
This is all very abstract, however. Here is a C# example:
class Program
{
static void Main()
{
// This is a local variable. Its lifespan
// is determined by lexical scope.
Foo foo;
}
}
class Foo
{
// This is a member variable - a new instance
// of this variable will be created for each
// new instance of Foo. The lifespan of this
// variable is equal to the lifespan of "this"
// instance of Foo.
int bar;
}
There are two kinds of member variable: instance and static.
An instance variable lasts as long as the instance of the class. There will be one copy of it per instance.
A static variable lasts as long as the class. There is one copy of it for the entire class.
A local variable is declared in a method and only lasts until the method returns:
public class Example {
private int _instanceVariable = 1;
private static int _staticvariable = 2;
public void Method() {
int localVariable = 3;
}
}
// Somewhere else
Example e = new Example();
// e._instanceVariable will be 1
// e._staticVariable will be 2
// localVariable does not exist
e.Method(); // While executing, localVariable exists
// Afterwards, it's gone
public class Foo
{
private int _FooInt; // I am a member variable
public void Bar()
{
int barInt; // I am a local variable
//Bar() can see barInt and _FooInt
}
public void Baz()
{
//Baz() can only see _FooInt
}
}
A local variable is the variable you declare in a function.Its lifespan is on that Function only.
A member variable is the variable you declare in a class definition.Its lifespan is inside that class only.It is Global Variable.It can be access by any function inside that same class.
Variables declared within a method are "local variables"
Variables declared within the class not within any methods are "member variables"(global variables).
Variables declared within the class not within any methods and defined as static are "class variables".
A member variable belongs to an object... something which has state. A local variable just belongs to the symbol table of whatever scope you are in. However, they will be represented in memory much the same as the computer has no notion of a class... it just sees bits which represent instructions. Local variables and member variables can both be on the stack or heap.