Sumit
Sumit

Reputation: 2023

Calling protected method in itcl

I am learning tcl. I am creating a class and writing a protected method. I am trying to call protected method using object but i am getting error

Below is the code in tcl

::itcl::class p5 {
    protected variable pec "5"

    #constructor {} {
    #   set pec 10
    #}
    protected method abc {} {puts " value of pec is $pec";}
}

p5 o5
o5 abc

I am getting below error

bad option "abc": should be one of...
  o5 cget -option
  o5 configure ?-option? ?value -option value...?
  o5 isa className

Any clues how to call protected method in class

Upvotes: 1

Views: 773

Answers (2)

Hai Vu
Hai Vu

Reputation: 40773

If you want to be able to call method abc, do not make it protected. Remove the keyword protected from the method declaration and your program should work.

Update

You can call your protected method within your class (i.e. from other methods within the same class). That's what it meant by protected. You can use Donal's method to by pass the protection, but that defeats the purpose of the protected keyword.

By the way, Donal's post inspired me to come up with another way to call protected methods:

package require Itcl

::itcl::class p5 {
    protected variable pec "5"

    protected method abc {} {puts " value of pec is $pec";}
    protected method greet {name1 name2} { puts "Hello $name1 and $name2" }

    method callProtectedMethod {methodName args} {
        eval [$methodName {*}$args]
    }
}

p5 o5
o5 callProtectedMethod abc
o5 callProtectedMethod greet Harry Sally

My approach creates a public method callProtectedMethod and it allows calling of any protected methods. Again, while this work, I highly recommend removing the protected keyword if you absolutely need to call it.

Upvotes: 2

Donal Fellows
Donal Fellows

Reputation: 137767

You can't call a protected method from outside the context of the instance of the class (or the instance of a subclass); that's the whole point of it being protected. But you can use itcl::code to get into the context, which is great for generating callbacks. Of course, you have to use itcl::code from already inside the context.

::itcl::class p5 {
    protected variable pec "5"
    protected method abc {} {puts " value of pec is $pec";}

    public method getAbcCaller {} {
        return [itcl::code $this abc]
    }
}

Testing it out:

% p5 o5
o5
% o5 abc
bad option "abc": should be one of...
  o5 cget -option
  o5 configure ?-option? ?value -option value...?
  o5 getAbcCaller
  o5 isa className
% eval [o5 getAbcCaller]
 value of pec is 5

Upvotes: 3

Related Questions