• Something odd with [oo::class create] on Tcl 8.6.13

    From Alan Grunwald@[email protected] to comp.lang.tcl on Mon Mar 11 16:02:10 2024
    From Newsgroup: comp.lang.tcl

    Consider:

    % oo::class create foo {constructor {} {}}
    ::foo
    % set f [foo new]
    ::oo::Obj12
    % set g [foo new a b c]
    ::oo::Obj13

    I'd expect the second attempt to create an object to fail because there
    are too many arguments.

    Also:

    % oo::class create foo {constructor {a} {}}
    ::foo
    % set f [foo new]
    ::oo::Obj12
    % set f [foo new a b c]
    ::oo::Obj13

    I'd expect both attempts to create objects to fail because neither
    specifies the correct number of arguments.

    Have I misunderstood something (if so, what) or is there a bug here?
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Joerg Mertens@[email protected] to comp.lang.tcl on Mon Mar 11 23:00:29 2024
    From Newsgroup: comp.lang.tcl

    Alan Grunwald <[email protected]> writes:

    Consider:

    % oo::class create foo {constructor {} {}}
    ::foo
    % set f [foo new]
    ::oo::Obj12
    % set g [foo new a b c]
    ::oo::Obj13

    I'd expect the second attempt to create an object to fail because
    there are too many arguments.

    Also:

    % oo::class create foo {constructor {a} {}}
    ::foo
    % set f [foo new]
    ::oo::Obj12
    % set f [foo new a b c]
    ::oo::Obj13

    I'd expect both attempts to create objects to fail because neither
    specifies the correct number of arguments.

    Have I misunderstood something (if so, what) or is there a bug here?

    Looks like the constructor is not even created if the body is empty. As
    soon as you put something in the body the arguments are checked:

    % oo::class create foo {constructor {a} {puts hello}}
    ::foo
    % set f [foo new a b c]
    wrong # args: should be "foo new a"

    Otherwise the behaviour is the same as if the class has no constructor
    at all - you can provide an arbitrary number of arguments.

    The question remains why these are not checked.
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Ralf Fassel@[email protected] to comp.lang.tcl on Tue Mar 12 12:19:11 2024
    From Newsgroup: comp.lang.tcl

    * Joerg Mertens <[email protected]>
    | Alan Grunwald <[email protected]> writes:
    | > % oo::class create foo {constructor {a} {}}
    | > ::foo
    | > % set f [foo new]
    | > ::oo::Obj12
    | > % set f [foo new a b c]
    | > ::oo::Obj13
    | >
    | > I'd expect both attempts to create objects to fail because neither
    | > specifies the correct number of arguments.
    | >
    | > Have I misunderstood something (if so, what) or is there a bug here?

    | Looks like the constructor is not even created if the body is empty. As
    | soon as you put something in the body the arguments are checked:

    Even an comment is sufficient to trigger this:

    % oo::class create foo {constructor {} {#;}}
    ::foo
    % set g [foo new a b c]
    wrong # args: should be "foo new"

    But I would file "not checking the arguments" under 'bug' anyway...

    R'
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Alan Grunwald@[email protected] to comp.lang.tcl on Thu Mar 14 09:52:26 2024
    From Newsgroup: comp.lang.tcl

    On 12/03/2024 11:19, Ralf Fassel wrote:
    * Joerg Mertens <[email protected]>
    | Alan Grunwald <[email protected]> writes:
    | > % oo::class create foo {constructor {a} {}}
    | > ::foo
    | > % set f [foo new]
    | > ::oo::Obj12
    | > % set f [foo new a b c]
    | > ::oo::Obj13
    | >
    | > I'd expect both attempts to create objects to fail because neither
    | > specifies the correct number of arguments.
    | >
    | > Have I misunderstood something (if so, what) or is there a bug here?

    | Looks like the constructor is not even created if the body is empty. As
    | soon as you put something in the body the arguments are checked:

    Even an comment is sufficient to trigger this:

    % oo::class create foo {constructor {} {#;}}
    ::foo
    % set g [foo new a b c]
    wrong # args: should be "foo new"

    But I would file "not checking the arguments" under 'bug' anyway...

    R'

    Thanks Joerg, Ralf. I didn't realise that the default constructor (if
    none was specified) would accept an arbitrary number of arguments.

    I'll raise a bug report about the differing behaviour between a
    constructor with and without a body.

    Alan
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Alan Grunwald@[email protected] to comp.lang.tcl on Thu Mar 14 10:37:43 2024
    From Newsgroup: comp.lang.tcl

    On 14/03/2024 09:52, Alan Grunwald wrote:
    On 12/03/2024 11:19, Ralf Fassel wrote:
    * Joerg Mertens <[email protected]>
    | Alan Grunwald <[email protected]> writes:
    | >     % oo::class create foo {constructor {a} {}}
    | >     ::foo
    | >     % set f [foo new]
    | >     ::oo::Obj12
    | >     % set f [foo new a b c]
    | >     ::oo::Obj13
    | >
    | > I'd expect both attempts to create objects to fail because neither
    | > specifies the correct number of arguments.
    | >
    | > Have I misunderstood something (if so, what) or is there a bug here?

    | Looks like the constructor is not even created if the body is empty. As
    | soon as you put something in the body the arguments are checked:

    Even an comment is sufficient to trigger this:

         % oo::class create foo {constructor {} {#;}}
         ::foo
         % set g [foo new a b c]
         wrong # args: should be "foo new"

    But I would file "not checking the arguments" under 'bug' anyway...

    R'

    Thanks Joerg, Ralf. I didn't realise that the default constructor (if
    none was specified) would accept an arbitrary number of arguments.

    I'll raise a bug report about the differing behaviour between a
    constructor with and without a body.

    Alan

    I've raised ticket [7a0f53f4] in the core fossil repo - I hope that's
    the right place.

    In the course of reformulating the example, I discovered that a single
    space is sufficient to cause he arguments to be checked.

    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Alan Grunwald@[email protected] to comp.lang.tcl on Tue May 28 23:00:31 2024
    From Newsgroup: comp.lang.tcl

    On 14/03/2024 10:37, Alan Grunwald wrote:
    On 14/03/2024 09:52, Alan Grunwald wrote:
    On 12/03/2024 11:19, Ralf Fassel wrote:
    * Joerg Mertens <[email protected]>
    | Alan Grunwald <[email protected]> writes:
    | >     % oo::class create foo {constructor {a} {}}
    | >     ::foo
    | >     % set f [foo new]
    | >     ::oo::Obj12
    | >     % set f [foo new a b c]
    | >     ::oo::Obj13
    | >
    | > I'd expect both attempts to create objects to fail because neither
    | > specifies the correct number of arguments.
    | >
    | > Have I misunderstood something (if so, what) or is there a bug here? >>>>
    | Looks like the constructor is not even created if the body is
    empty. As
    | soon as you put something in the body the arguments are checked:

    Even an comment is sufficient to trigger this:

         % oo::class create foo {constructor {} {#;}}
         ::foo
         % set g [foo new a b c]
         wrong # args: should be "foo new"

    But I would file "not checking the arguments" under 'bug' anyway...

    R'

    Thanks Joerg, Ralf. I didn't realise that the default constructor (if
    none was specified) would accept an arbitrary number of arguments.

    I'll raise a bug report about the differing behaviour between a
    constructor with and without a body.

    Alan

    I've raised ticket [7a0f53f4] in the core fossil repo - I hope that's
    the right place.

    In the course of reformulating the example, I discovered that a single
    space is sufficient to cause he arguments to be checked.

    I've had a response to this ticket from Donal Fellows. He drew my
    attention to the statement in the contructor section of the oo::define
    manpage that reads "If bodyScript is the empty string, the constructor
    will be deleted". This certainly explains the difference in behaviour
    between

    oo::class create foo {constructor {} {}}

    and

    oo::class create foo {constructor {} { }}

    However, I wasn't expecting that if I fail to specify a constructor
    explicitly when defining a class, then the default constructor accepts
    any (or no) arguments. It strikes me that if you don't define a
    constructor then you'd expect the default constructor to accept *no*
    arguments and that if you later create an instance of the class passing
    some arguments, then that creation is an error.

    If enough people agree with me, I'll have a go at persuading Donal to
    reopen the ticket and change the default constructor.
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Ralf Fassel@[email protected] to comp.lang.tcl on Wed May 29 11:00:31 2024
    From Newsgroup: comp.lang.tcl

    * Alan Grunwald <[email protected]>
    | > On 14/03/2024 09:52, Alan Grunwald wrote:
    | > I've raised ticket [7a0f53f4] in the core fossil repo - I hope
    | > that's the right place.
    | > In the course of reformulating the example, I discovered that a
    | > single space is sufficient to cause he arguments to be checked.
    | >
    | I've had a response to this ticket from Donal Fellows. He drew my
    | attention to the statement in the contructor section of the oo::define
    | manpage that reads "If bodyScript is the empty string, the constructor
    | will be deleted". This certainly explains the difference in behaviour
    | between

    | oo::class create foo {constructor {} {}}

    | and

    | oo::class create foo {constructor {} { }}

    | However, I wasn't expecting that if I fail to specify a constructor
    | explicitly when defining a class, then the default constructor accepts
    | any (or no) arguments. It strikes me that if you don't define a
    | constructor then you'd expect the default constructor to accept *no*
    | arguments and that if you later create an instance of the class
    | passing some arguments, then that creation is an error.

    I'd second that. This is how c++ does it (there even the
    wrong type of argument results in compilation error).

    | If enough people agree with me, I'll have a go at persuading Donal to
    | reopen the ticket and change the default constructor.

    I would think that if I need a CTOR which accepts (and probably
    discards) any number of arguments, then creating one accepting 'args'
    would be the way to go.

    R'
    --- Synchronet 3.20a-Linux NewsLink 1.114