itcl::class base {
protected variable LIST {a}
protected variable a "1";
public method show { } {
foreach arg $LIST {
puts "${arg}: [set $arg]"
}
}
}
itcl::class derived {
inherit base
protected variable b "3";
protected variable c "4";
constructor { } {
set LIST {a b c}
set a "2";
}
}
derived x
x show
What I WANT this to do is to loop through the current value of LIST and show
the values of those members at that time (i.e. they can change over time). I
guess it's a bit like a "-configure" statement, but I want to control which
variables get listed, and in which format.
When I execute this, I get an error that base::show cannot find "b".
Obviously - there is no such thing as base::b. I want it to find
derived::b. I want it to execute show in the scope of ::derived.
Is this possible? I've tried various incantations of "uplevel", "chain" and
"virtual" to no effect (just get similar errors).
The whole point of writing this in the base class is that I don't want to
have to repeat the identical code in the derived class(es).
Comments?
Thanks,
MH
You can access the *public* variables of derived classes through
[cget]. This builtin method looks in the current object's context for
the respective variable, while substitution and [set] just look in the
current class context (where the derived class'es variables are not
visible). So, the [show] method has to be changed:
itcl::body base::show {} {
foreach arg $LIST {
puts "$arg: [cget -$arg]"
}
}
Eckhard
Any way to do this with PRIVATE variables?
Mattias
Ah, found it!
itcl::body base::show {} {
foreach arg $LIST {
puts "$arg: [$this info variable $arg -value]"
}
}
Mattias
>
> Any way to do this with PRIVATE variables?
>
> Mattias
No, but with protected variables:
install my patch for [cget] code - a fragment of code that is
associated with variables (public and protected) and executed on
[cget]... for public variables it works from outside and inside object
methods, for protected ones it works from inside methods only, but also
with derived/base objects. For that to be possible I made changes to
the builtin [cget] method, so that [cget] can be called on protected
variables inside methods.
You find it along with a discussion on my website:
http://e-lehmann.de/?page_id=14. I also submitted it to the official
patch management interface on sourceforge
(http://sourceforge.net/tracker/?group_id=13244&atid=313244), but I
don't know what happens to it there... at least I got no feedback so
far.
It seems that the community's interrest in Itcl has become very sparse
since XOTcl is out and TIP 257 was proposed. But in my opinion it is
still the most practical and usable object system for Tcl, especially
together with Itk.
Eckhard
Ah, ok.. Protected variables will do.
>You find it along with a discussion on my website:
>http://e-lehmann.de/?page_id=14. I also submitted it to the official
>patch management interface on sourceforge
>(http://sourceforge.net/tracker/?group_id=13244&atid=313244), but I
>don't know what happens to it there... at least I got no feedback so
>far.
>It seems that the community's interrest in Itcl has become very sparse
>since XOTcl is out and TIP 257 was proposed. But in my opinion it is
>still the most practical and usable object system for Tcl, especially
>together with Itk.
I have never used XOTcl, we're using Itcl...
Now, I have to convince people to use your patch. btw, what license are you
releasing it under?
Also, any ideas on how to make the "info" part of an Itcl class
protected/private, so it can only be called from within methods? That would
probably suffice for my problem, acutally.
Or, I can just work around it, and write some extra code..
Thanks,
Mattias
The same licence as Itcl itself... I should state this more clearly on
my site.
>
> Also, any ideas on how to make the "info" part of an Itcl class
> protected/private, so it can only be called from within methods? That would
> probably suffice for my problem, acutally.
>
> Or, I can just work around it, and write some extra code..
Actually, [info] should be public. It gives you the possibility to
query classes and objects from outside and get dynamic runtime
information about them. This is an important feature of dynamic
languages like Tcl, compared to statically compiled languages...
You can still use [info] from inside, and if you don't want to, you
don't need to use it from outside...
Eckhard
Ok, thanks.
>> Also, any ideas on how to make the "info" part of an Itcl class
>> protected/private, so it can only be called from within methods? That would
>> probably suffice for my problem, acutally.
>>
>> Or, I can just work around it, and write some extra code..
>
>Actually, [info] should be public. It gives you the possibility to
>query classes and objects from outside and get dynamic runtime
>information about them. This is an important feature of dynamic
>languages like Tcl, compared to statically compiled languages...
>You can still use [info] from inside, and if you don't want to, you
>don't need to use it from outside...
>
>
>Eckhard
Umm, sure, but.. What if you absolutely don't WANT people to be able to see
your procs, for example, because you have some IP that you don't want to
give away?
I've been able to do that by declaring "protected method info { } { }"
inside my classes. And, using a slave interpreter, we can get around
::itcl::code, so we can protect against that..
Any other ideas about security?
Mattias
Mattias
I'd do it the same way - overriding [info] and declare it protected is
a good idea.
Eckhard
Eckhard