Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

TclOO and [+ 1 2] in Ashok's book gives me an error

60 views
Skip to first unread message

two...@gmail.com

unread,
Apr 9, 2019, 4:46:09 PM4/9/19
to
I'm trying to learn TclOO and am following along with Ashok's book.
He uses math operators by using

namespace path ::tcl::mathop

which lets him use the arithmetic operators like + as such,

set Balance [+ $Balance $change]

However, in his example creating a class Account, I get an error
if I don't place the namespace path statement inside the method
definition itself.

For example,

% namespace path ::tcl::mathop
% proc testp {} {puts [+ 1 2]}
% testp
3

% oo::class create Account
::Account
% oo::define Account {
> method test {} {puts [+ 1 2]}
> }

% set acct [Account new]
::oo::Obj52
% $acct test
invalid command name "+" <<<<<<<<<<<<<< error here

% oo::define Account {
> method test2 {} {namespace path ::tcl::mathop ; puts [+ 1 2]}
> }
% $acct test2
3

How can I get these math ops to work everywhere so I can
copy/paste his example code and get it to work w/o
having to edit it?

Ashok

unread,
Apr 9, 2019, 11:32:25 PM4/9/19
to
That code generating the error is not actually in the book is it? It
would need to be added to the errata if it is but I couldn't locate it
in the book.

In any case, to answer your question, namespace path command only
affects resolution of namespaces within the namespace from which it is
called. Thus calling at the global scope only affects resolution in the
global scope.

To change the namespace path for all methods of a class, you need to add
it to the class constructor. For example,

% oo::class create C {
constructor {} {
namespace path [linsert [namespace path] 0 ::tcl::mathop]
}
method test {} {puts [+ 2 2]}
}
::C
% C create c
::c
% c test
4
%

/Ashok

two...@gmail.com

unread,
Apr 10, 2019, 1:08:07 AM4/10/19
to
On Tuesday, April 9, 2019 at 8:32:25 PM UTC-7, Ashok wrote:
> That code generating the error is not actually in the book is it? It
> would need to be added to the errata if it is but I couldn't locate it
> in the book.
>

Sorry I posted my own simpler example, however, I did initially try
one from the book,

section 14.2.4 Defining methods, the example

oo::define Account {
method UpdateBalance {change} {
set Balance [+ $Balance $change]
return $Balance
}
method balance {} { return $Balance }
method withdraw {amount} {
return [my UpdateBalance -$amount]
}
method deposit {amount} {
return [my UpdateBalance $amount]
}
}

And it gets the error,

> In any case, to answer your question,
> constructor {} {
> namespace path [linsert [namespace path] 0 ::tcl::mathop]
> }

But this does indeed do the job. I don't think you mention needing
this in the book, at least not along with your example above. And
constructors are later in the book, 14.2.5. I used them with the
above code.

So, from what I can see I can get away with just the one global
level namespace command for all proc's (in same interpreter I imagine)
but for objects, one needs one per class definition.

Thanks.

BTW, hope your next book is on TK and especially the ttk themes.

I use pdf-xchange viewer, a free portable pdf reader. Being searchable
and able to copy/paste for testing is a great resource.
The 1 sided pdf displays great with toc on left, search on right.



Donal K. Fellows

unread,
Apr 10, 2019, 4:42:39 AM4/10/19
to
On 10/04/2019 04:32, Ashok wrote:
> To change the namespace path for all methods of a class, you need to add
> it to the class constructor.

I want to make that easier sometime…

Donal.
--
Donal Fellows — Tcl user, Tcl maintainer, TIP editor.

Ashok

unread,
Apr 10, 2019, 5:26:11 AM4/10/19
to
Thanks for the detailed response. I was a little surprised at the
failure because *almost* all scripts in the book are executed as part of
the book build process and I had no seen any failures. As it turns out,
the culprit was a

namespace import ::tcl::mathop::*

earlier in the build script itself which made the math operators visible
in the example code. So an alternative to make the operators available
in methods would be

% namespace import tcl::mathop::*
% oo::class create C {
method test {} {puts [+ 2 2]}
}
::C
% C create c
::c
% c test
4

Personally, I would not recommend this global level import though
convenient as it introduces the operator visibility in all other
namespaces as well.

/Ashok
0 new messages