Reputation: 1798
Inside a constructor, destructor or method, can I find out what namespace the class was created in, so I can just call card
in my other classes instead of hard coding it as blackjack::card
?
namespace eval blackjack {
oo::class create card {
...
}
oo::class create deck {
constructor {} {
my variable cards
set cards {}
for {set suit 0} {$suit < 4} {incr suit} {
for {set value 0} {$value < 13} {incr value} {
lappend cards [blackjack::card new $suit $value]
}
}
}
...
}
}
Upvotes: 2
Views: 132
Reputation: 137767
You already know this, and it is what I actually do almost always as it's direct and simple. (It's “Option 0” because it un-asks the question.)
uplevel
You could do:
lappend cards [uplevel 1 [list card new $suit $value]]
But that depends on the deck new
being called from the right namespace.
If we assume that the two classes are in the same namespace:
constructor {} {
set cardClass [namespace qualifiers [self class]]::card
# ...
lappend cards [$cardClass new $suit $value]
# ...
}
namespace path
If you add to the object's path (NB: must be done on a per-object basis in the constructor right now) then you can refer to the other class simply:
constructor {} {
namespace path [list {*}[namespace path] ::blackjack]
# ...
lappend cards [card new $suit $value]
# ...
}
The main thing to watch out here is that TclOO sets a non-trivial default namespace path
(where do you think that next
and self
come from?)
You have another option, and that is to use namespace export
and namespace import
to make a command link.
First, export the relevant classes from the ::blackjack
namespace:
namespace eval ::blackjack {
namespace export card; # You probably want to export “deck” as well
# ...
}
Then, do the import in the constructor:
constructor {} {
namespace import ::blackjack::card
# ...
lappend cards [card new $suit $value]
# ...
}
deck
instanceThis one is tricky!
constructor {} {
oo::class create card {superclass ::blackjack::card}
# ...
lappend cards [card new $suit $value]
# ...
}
This also means that the cards will be automatically deleted when the deck goes away; you don't need to destroy them in the destructor (because their actual class will be automatically removed, and that kills the instances). That might or might not be what you need. (It does make for a good way of modeling a UML composition relation; TDBC uses a variation on this internally to associate statements with connections and result sets with statements.)
Upvotes: 4