Prev: I'm so sorry! [was: Integer math problem]
Next: TclOO and inheritance - example from the wiki does not work anymore ...
From: MartinLemburg on 15 Feb 2010 06:38 Hi, I just started to try TclOO and using OO until now only in C++, I really miss the ability to define operators for "system internal actions". I didn't find until now the ability to define e.g. a "==" or "eq" operator, so that an object can be tested for equality not using its "address", but a kind of algorithm hided within the object. Did I miss something or is something similar planed to be done in the near future? Or is my OO thinking too much influenced from my C++ work? (wouldn't be that surprising!) Best regards, Martin
From: George Petasis on 15 Feb 2010 08:16 στις 15/2/2010 13:38, O/H MartinLemburg(a)Siemens-PLM έγραψε: > Hi, > > I just started to try TclOO and using OO until now only in C++, I > really miss the ability to define operators for "system internal > actions". > > I didn't find until now the ability to define e.g. a "==" or "eq" > operator, so that an object can be tested for equality not using its > "address", but a kind of algorithm hided within the object. > > Did I miss something or is something similar planed to be done in the > near future? > > Or is my OO thinking too much influenced from my C++ work? (wouldn't > be that surprising!) > > Best regards, > > Martin Dear Martin, Have you tried to define a method named == ? package require TclOO oo::class create A { method == {obj} { return false } export == } set a [A new] set b [A new] puts [$a == $b] George
From: MartinLemburg on 15 Feb 2010 10:25 Hi George, I don't mind calling a method "==" or "isEqual" or "foo"! But I do mind, if I can use an object within an expression or other contexts without doing too much work! One thing coming to my mind was something like a class having several "cast" methods ... % oo::class create foo { variable m_value; constructor {value} { my variable m_value; set m_value $value; if {[string is double -strict $value]} { oo::objdefine [self] method AsDouble {} [list return [expr {double($value)}]]; if {[string is integer -strict $value]} { oo::objdefine [self] method AsInt {} [list return [expr {int($value)}]]; oo::objdefine [self] method AsWide {} [list return [expr {wide($value)}]]; } elseif {[string is wide -strict $value]} { oo::objdefine [self] method AsWide {} [list return [expr {wide($value)}]]; } } if {[string is boolean -strict $value]} { oo::objdefine [self] method AsBool {} [list return [string is true -strict $value]]; } oo::objdefine [self] method AsString {} [list return [string toupper $value]]; } } ::foo % foo create obj 3 ::obj % expr {int(obj)/double(obj)}; # bare word obj is not a function, but an "object" having AsInt and AsDouble methods 1.0 % expr {int(obj)/int(obj)} 1 % foo create obj2 10 ::obj2 % foo create obj3 1 ::obj3 % lsort -integer [list obj obj2 obj3] obj3 obj obj2 % lsort [list obj obj2 obj3] obj3 obj2 obj % lsort -dictionary [list obj obj2 obj3] obj3 obj obj2 I know the example above is not really tcl'ish, but IMHO it would be very nice to have data related behavior controlled by probably defined and implicitly used "cast" methods. Using the class/object from above more tcl'ish would be: % expr {[obj AsInt]/[obj AsDouble]} 1.0 % expr {[obj AsInt]/[obj AsInt]} 1 % set sortCmd {apply {{cast o1 o2} { if {[$o1 AsInt] < [$o2 AsInt]} { return -1; } elseif {[$o1 AsInt] > [$o2 AsInt]} { return 1; } return 0; }}}; puts "" % lsort -command [list $sortCmd AsInt] {obj obj2 obj3} obj3 obj obj2 % lsort -command [list $sortCmd AsString] {obj obj2 obj3} obj3 obj2 obj % lsort -command {apply {{o1 o2} { set v1 [$o1 AsString]; set v2 [$o2 AsString]; if {$v1 eq $v2} { return 0; } set sorted [lsort -dictionary [list $v1 $v2]]; set first [lindex $sorted 0]; if {$first eq $v1} { return -1; } return 1; }}} {obj obj2 obj3} obj3 obj obj2 The more I write this, the more a german word (more slang word) comes to my mind (meaning something like silly/crazy) "spinnert". But on the other hand even in C++ I always liked cast operators! :( Any opinions? Best regards, Martin Lemburg George Petasis schrieb: > ÏÏÎ¹Ï 15/2/2010 13:38, O/H MartinLemburg(a)Siemens-PLM ÎγÏαÏε: > > Hi, > > > > I just started to try TclOO and using OO until now only in C++, I > > really miss the ability to define operators for "system internal > > actions". > > > > I didn't find until now the ability to define e.g. a "==" or "eq" > > operator, so that an object can be tested for equality not using its > > "address", but a kind of algorithm hided within the object. > > > > Did I miss something or is something similar planed to be done in the > > near future? > > > > Or is my OO thinking too much influenced from my C++ work? (wouldn't > > be that surprising!) > > > > Best regards, > > > > Martin > > Dear Martin, > > Have you tried to define a method named == ? > > package require TclOO > > oo::class create A { > > method == {obj} { > return false > } > > export == > } > > set a [A new] > set b [A new] > > puts [$a == $b] > > George
From: Donal K. Fellows on 15 Feb 2010 11:37 On 15 Feb, 11:38, "MartinLemburg(a)Siemens-PLM" <martin.lemburg.siemens-...(a)gmx.net> wrote: > I didn't find until now the ability to define e.g. a "==" or "eq" > operator, so that an object can be tested for equality not using its > "address", but a kind of algorithm hided within the object. > > Did I miss something or is something similar planed to be done in the > near future? I was not planning to do this. An equivalence comparison method could be added, though given TclOO's state model it would have to default to being equality of object names (or namespace names), but I don't really see a lot of need since Tcl's objects are higher-level entities anyway. I'm definitely not going to work on plugging into the expression operator system. That's a part of Tcl that currently requires hacking inside tclExecute.c (or writing your own expression parser) to change at all, so is not recommended for, well, anyone at all. > Or is my OO thinking too much influenced from my C++ work? (wouldn't > be that surprising!) It is rather C++ish. :-) But we can steal a few leaves out of Java's book here (and also use the fact that all classes are modifiable after the fact). Here's an example to get you started: oo::define oo::object { method == object {string equal [self] [namespace which $object]} # Does not start with lower-case letter, so not exported by default # Thus we must export it here for it to be part of public API export == } set o1 [oo::object new] set o2 $o1 set o3 [oo::object new] puts [$o1 == $o2],[$o1 == $o3],[oo::class == oo::object] puts [[info object class $o1] == oo::object] Note that the == method is just an ordinary method. Nothing special at all. :-) Donal.
From: Georgios Petasis on 15 Feb 2010 12:01
Dear Martin, I think that all these are doable, at least from the C level. But you have to check whether implementing them justifies the effort. The easier of all, it to modify the behavior of expr. Since all expr functions are commands in the ::tcl::mathfunc namespace, they can be modified: rename ::tcl::mathfunc::int ::tcl::mathfunc::int_original proc ::tcl::mathfunc::int {argument} { ## Check if argument is an object. If it is, return the proper value. ## If it is not, just return the original behavior: return [::tcl::mathfunc::int_original] } If you want objects to be able to be casted to integers or strings, then you need to create a custom tcl object type (from C), that can hold a tcloo object. This way, when a conversion is requested by Tcl internals, you can arrange to call a method from the object. But what will be the added value of all these? George στις 15/2/2010 17:25, O/H MartinLemburg(a)Siemens-PLM έγραψε: > Hi George, > > I don't mind calling a method "==" or "isEqual" or "foo"! > > But I do mind, if I can use an object within an expression or other > contexts without doing too much work! > > One thing coming to my mind was something like a class having several > "cast" methods ... > > % oo::class create foo { > variable m_value; > > constructor {value} { > my variable m_value; > > set m_value $value; > > if {[string is double -strict $value]} { > oo::objdefine [self] method AsDouble {} [list return > [expr {double($value)}]]; > > if {[string is integer -strict $value]} { > oo::objdefine [self] method AsInt {} [list return > [expr {int($value)}]]; > oo::objdefine [self] method AsWide {} [list return > [expr {wide($value)}]]; > } elseif {[string is wide -strict $value]} { > oo::objdefine [self] method AsWide {} [list return > [expr {wide($value)}]]; > } > } > > if {[string is boolean -strict $value]} { > oo::objdefine [self] method AsBool {} [list return > [string is true -strict $value]]; > } > > oo::objdefine [self] method AsString {} [list return > [string toupper $value]]; > } > } > ::foo > % foo create obj 3 > ::obj > % expr {int(obj)/double(obj)}; # bare word obj is not a function, > but an "object" having AsInt and AsDouble methods > 1.0 > % expr {int(obj)/int(obj)} > 1 > % foo create obj2 10 > ::obj2 > % foo create obj3 1 > ::obj3 > % lsort -integer [list obj obj2 obj3] > obj3 obj obj2 > % lsort [list obj obj2 obj3] > obj3 obj2 obj > % lsort -dictionary [list obj obj2 obj3] > obj3 obj obj2 > > I know the example above is not really tcl'ish, but IMHO it would be > very nice to have data related behavior controlled by probably defined > and implicitly used "cast" methods. > > Using the class/object from above more tcl'ish would be: > > % expr {[obj AsInt]/[obj AsDouble]} > 1.0 > % expr {[obj AsInt]/[obj AsInt]} > 1 > % set sortCmd {apply {{cast o1 o2} { > if {[$o1 AsInt]< [$o2 AsInt]} { > return -1; > } elseif {[$o1 AsInt]> [$o2 AsInt]} { > return 1; > } > > return 0; > }}}; puts "" > % lsort -command [list $sortCmd AsInt] {obj obj2 obj3} > obj3 obj obj2 > % lsort -command [list $sortCmd AsString] {obj obj2 obj3} > obj3 obj2 obj > % lsort -command {apply {{o1 o2} { > set v1 [$o1 AsString]; > set v2 [$o2 AsString]; > > if {$v1 eq $v2} { > return 0; > } > > set sorted [lsort -dictionary [list $v1 $v2]]; > set first [lindex $sorted 0]; > > if {$first eq $v1} { > return -1; > } > > return 1; > }}} {obj obj2 obj3} > obj3 obj obj2 > > The more I write this, the more a german word (more slang word) comes > to my mind (meaning something like silly/crazy) "spinnert". > But on the other hand even in C++ I always liked cast operators! :( > > Any opinions? > > Best regards, > > Martin Lemburg > > George Petasis schrieb: >> στις 15/2/2010 13:38, O/H MartinLemburg(a)Siemens-PLM έγραψε: >>> Hi, >>> >>> I just started to try TclOO and using OO until now only in C++, I >>> really miss the ability to define operators for "system internal >>> actions". >>> >>> I didn't find until now the ability to define e.g. a "==" or "eq" >>> operator, so that an object can be tested for equality not using its >>> "address", but a kind of algorithm hided within the object. >>> >>> Did I miss something or is something similar planed to be done in the >>> near future? >>> >>> Or is my OO thinking too much influenced from my C++ work? (wouldn't >>> be that surprising!) >>> >>> Best regards, >>> >>> Martin >> >> Dear Martin, >> >> Have you tried to define a method named == ? >> >> package require TclOO >> >> oo::class create A { >> >> method == {obj} { >> return false >> } >> >> export == >> } >> >> set a [A new] >> set b [A new] >> >> puts [$a == $b] >> >> George |