Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch tip-519 Excluding Merge-Ins
This is equivalent to a diff from 91d01941b7 to d7cc3f28f1
2018-11-06
| ||
11:13 | Implement TIP 519 check-in: fb31dee0c8 user: dkf tags: core-8-branch | |
2018-10-21
| ||
10:50 | Squash warnings in the OSX notifier check-in: fbe54d6901 user: dkf tags: core-8-branch | |
10:01 | Remove unused variable Closed-Leaf check-in: d7cc3f28f1 user: dkf tags: tip-519 | |
09:57 | More tests. Better implementation. check-in: ab589541b2 user: dkf tags: tip-519 | |
2018-10-20
| ||
23:41 | Rebase on 8.7 check-in: 9367b0eaf1 user: dkf tags: tip-519 | |
21:03 | Working on porting the travis config forward check-in: b321d38e15 user: dkf tags: travis-8.7 | |
2018-10-19
| ||
19:22 | merge 8.7 check-in: cf76bede4f user: jan.nijtmans tags: tip-481 | |
19:18 | [d1d05d1c7a] Tests and fix for bignums in end-offset index value parsing. check-in: a9a1abe2b6 user: dgp tags: bug-d1d05d1c7a | |
15:53 | Merge 8.7 check-in: 8c57795bed user: jan.nijtmans tags: trunk | |
15:52 | Merge 8.6 check-in: 91d01941b7 user: jan.nijtmans tags: core-8-branch | |
15:51 | Add support for "nostub" in genStubs.tcl. Not used by Tcl 8.6, but might be used by Tk 8.7 when link... check-in: f727d78283 user: jan.nijtmans tags: core-8-6-branch | |
10:06 | merge core-8-6-branch check-in: 4dfba7fb0e user: dkf tags: core-8-branch | |
Changes to doc/define.n.
︙ | ︙ | |||
136 137 138 139 140 141 142 | \fBinitialize\fI script\fR .VS TIP478 This evaluates \fIscript\fR in a context which supports local variables and where the current namespace is the instance namespace of the class object itself. This is useful for setting up, e.g., class-scoped variables. .VE TIP478 .TP | | | > > > > > | | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | \fBinitialize\fI script\fR .VS TIP478 This evaluates \fIscript\fR in a context which supports local variables and where the current namespace is the instance namespace of the class object itself. This is useful for setting up, e.g., class-scoped variables. .VE TIP478 .TP \fBmethod\fI name \fR?\fIoption\fR? \fIargList bodyScript\fR . This creates or updates a method that is implemented as a procedure-like script. The name of the method is \fIname\fR, the formal arguments to the method (defined using the same format as for the Tcl \fBproc\fR command) will be \fIargList\fR, and the body of the method will be \fIbodyScript\fR. When the body of the method is evaluated, the current namespace of the method will be a namespace that is unique to the current object. The method will be exported if \fIname\fR starts with a lower-case letter, and non-exported otherwise; this behavior can be overridden via \fBexport\fR and \fBunexport\fR .VS TIP519 or by specifying \fB\-export\fR, \fB\-private\fR or \fB\-unexport\fR in the optional parameter \fIoption\fR. .VE TIP519 .RS .PP .VS TIP500 If in a private definition context (see the \fBprivate\fR definition command, below) or if the \fB\-private\fR flag is given for \fIoption\fR, this command creates private procedure-like methods. .VE TIP500 .RE .TP \fBmixin\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR? . This slot (see \fBSLOTTED DEFINITIONS\fR below) sets or updates the list of additional classes that are to be mixed into |
︙ | ︙ | |||
317 318 319 320 321 322 323 | .PP .VS TIP500 If in a private definition context (see the \fBprivate\fR definition command, below), this command creates private forwarded methods. .VE TIP500 .RE .TP | | | > > > > > > | | 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 | .PP .VS TIP500 If in a private definition context (see the \fBprivate\fR definition command, below), this command creates private forwarded methods. .VE TIP500 .RE .TP \fBmethod\fI name \fR?\fIoption\fR? \fIargList bodyScript\fR . This creates, updates or deletes an object method. The name of the method is \fIname\fR, the formal arguments to the method (defined using the same format as for the Tcl \fBproc\fR command) will be \fIargList\fR, and the body of the method will be \fIbodyScript\fR. When the body of the method is evaluated, the current namespace of the method will be a namespace that is unique to the object. The method will be exported if \fIname\fR starts with a lower-case letter, and non-exported otherwise; .VS TIP519 this can be overridden by specifying \fB\-export\fR, \fB\-private\fR or \fB\-unexport\fR in the optional parameter \fIoption\fR, or via the \fBexport\fR and \fBunexport\fR definitions. .VE TIP519 .RS .PP .VS TIP500 If in a private definition context (see the \fBprivate\fR definition command, below) or if the \fB\-private\fR flag is given for \fIoption\fR, this command creates private procedure-like methods. .VE TIP500 .RE .TP \fBmixin\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR? . This slot (see \fBSLOTTED DEFINITIONS\fR below) sets or updates a per-object list of additional classes that are to be |
︙ | ︙ |
Changes to generic/tclOODefineCmds.c.
︙ | ︙ | |||
1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 | int TclOODefineMethodObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int isInstanceMethod = (clientData != NULL); Object *oPtr; int isPublic; | > > > > > > > > > > > > > > > > | | | | > > > > > > | > > > > > > > > > | | > > > > | | | 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 | int TclOODefineMethodObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { /* * Table of export modes for methods and their corresponding enum. */ static const char *const exportModes[] = { "-export", "-private", "-unexport", NULL }; enum ExportMode { MODE_EXPORT, MODE_PRIVATE, MODE_UNEXPORT } exportMode; int isInstanceMethod = (clientData != NULL); Object *oPtr; int isPublic; if (objc < 4 || objc > 5) { Tcl_WrongNumArgs(interp, 1, objv, "name ?option? args body"); return TCL_ERROR; } oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } if (!isInstanceMethod && !oPtr->classPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "attempt to misuse API", -1)); Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); return TCL_ERROR; } if (objc == 5) { if (Tcl_GetIndexFromObj(interp, objv[2], exportModes, "export flag", 0, (int *) &exportMode) != TCL_OK) { return TCL_ERROR; } switch (exportMode) { case MODE_EXPORT: isPublic = PUBLIC_METHOD; break; case MODE_PRIVATE: isPublic = TRUE_PRIVATE_METHOD; break; case MODE_UNEXPORT: isPublic = 0; break; } } else { if (IsPrivateDefine(interp)) { isPublic = TRUE_PRIVATE_METHOD; } else { isPublic = Tcl_StringMatch(TclGetString(objv[1]), "[a-z]*") ? PUBLIC_METHOD : 0; } } /* * Create the method by using the right back-end API. */ if (isInstanceMethod) { if (TclOONewProcInstanceMethod(interp, oPtr, isPublic, objv[1], objv[objc - 2], objv[objc - 1], NULL) == NULL) { return TCL_ERROR; } } else { if (TclOONewProcMethod(interp, oPtr->classPtr, isPublic, objv[1], objv[objc - 2], objv[objc - 1], NULL) == NULL) { return TCL_ERROR; } } return TCL_OK; } /* |
︙ | ︙ |
Changes to tests/oo.test.
︙ | ︙ | |||
125 126 127 128 129 130 131 | } }] lappend result [foo bar a b c] lappend result [foo destroy] [info commands foo] } {::foo {} a b c 3 {} {}} test oo-1.2 {basic test of OO functionality: no classes} -body { oo::define oo::object method missingArgs | | | | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | } }] lappend result [foo bar a b c] lappend result [foo destroy] [info commands foo] } {::foo {} a b c 3 {} {}} test oo-1.2 {basic test of OO functionality: no classes} -body { oo::define oo::object method missingArgs } -returnCodes 1 -result "wrong # args: should be \"oo::define oo::object method name ?option? args body\"" test oo-1.3 {basic test of OO functionality: no classes} { catch {oo::define oo::object method missingArgs} set errorInfo } "wrong # args: should be \"oo::define oo::object method name ?option? args body\" while executing \"oo::define oo::object method missingArgs\"" test oo-1.4 {basic test of OO functionality} -body { oo::object create {} } -returnCodes 1 -result {object name must not be empty} test oo-1.4.1 {fully-qualified nested name} -body { oo::object create ::one::two::three |
︙ | ︙ | |||
774 775 776 777 778 779 780 781 782 783 784 785 786 787 | unexport foo method foo {} {return ok} } [testClass new] foo } -cleanup { testClass destroy } -result ok test oo-5.1 {OO: manipulation of classes as objects} -setup { set obj [oo::object new] } -body { oo::objdefine oo::object method foo {} { return "in object" } catch {$obj foo} result list [catch {$obj foo} result] $result [oo::object foo] | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 | unexport foo method foo {} {return ok} } [testClass new] foo } -cleanup { testClass destroy } -result ok test oo-4.7 {basic test of OO functionality: method -export flag} -setup { set o [oo::object new] unset -nocomplain result } -body { oo::objdefine $o { method Foo {} { lappend ::result Foo return foo } method Bar -export {} { lappend ::result Bar return bar } } lappend result [catch {$o Foo} msg] $msg lappend result [$o Bar] } -cleanup { $o destroy } -result {1 {unknown method "Foo": must be Bar or destroy} Bar bar} test oo-4.8 {basic test of OO functionality: method -unexport flag} -setup { set o [oo::object new] unset -nocomplain result } -body { oo::objdefine $o { method foo {} { lappend ::result foo return Foo } method bar -unexport {} { lappend ::result bar return Bar } } lappend result [$o foo] lappend result [catch {$o bar} msg] $msg } -cleanup { $o destroy } -result {foo Foo 1 {unknown method "bar": must be destroy or foo}} test oo-4.9 {basic test of OO functionality: method -private flag} -setup { set o [oo::object new] unset -nocomplain result } -body { oo::objdefine $o { method foo {} { lappend ::result foo return Foo } method bar -private {} { lappend ::result bar return Bar } export eval method gorp {} { my bar } } lappend result [$o foo] lappend result [catch {$o bar} msg] $msg lappend result [catch {$o eval my bar} msg] $msg lappend result [$o gorp] } -cleanup { $o destroy } -result {foo Foo 1 {unknown method "bar": must be destroy, eval, foo or gorp} 1 {unknown method "bar": must be <cloned>, destroy, eval, foo, gorp, unknown, variable or varname} bar Bar} test oo-4.10 {basic test of OO functionality: method flag parsing} -setup { set o [oo::object new] } -body { oo::objdefine $o method foo -gorp xyz {return Foo} } -returnCodes error -cleanup { $o destroy } -result {bad export flag "-gorp": must be -export, -private, or -unexport} test oo-5.1 {OO: manipulation of classes as objects} -setup { set obj [oo::object new] } -body { oo::objdefine oo::object method foo {} { return "in object" } catch {$obj foo} result list [catch {$obj foo} result] $result [oo::object foo] |
︙ | ︙ |