Call of init method in component

Hi,

I looked through existing discussions if I could find something to clarify
my question about how the init method in components is called with Lucee
but couldn’t find much.
Btw. I think there are a lot of discussions here not focusing on specific
topics but containing a total mixture of everything that comes to mind
(especially in threads about the “future of Lucee” ;-))

My questions: how are init methods of components called with Lucee? With
creation of the object?
How do you pass a parameter or pass a return value that is not the object
(=this)?

I’m a little bit confused because during my research on the topic, I saw so
many different interpretations of how the init method is called and the
parameters are processed through different ACF versions and where it is
called implicitly on creation and where not.

Thanks a lot for clarifying!
Siegfried

Hi,

thanks for the many replies so far.

I like the answer of Walter Seethaler very much because you show and
explain the differences very well. But also the others pointed out one very
important aspect I thought it would be different:
you say calling createObject() without expicitly calling init() does not
call the constructor (init)? I thought it’s always called implicitly in all
of todays ColdFusion servers including Railo and Lucee?

But it probably makes the most sense because if I see it correctly using
the tag variant with is identical to createObject, and that was
also part of my question, how one would provide parameters for the implicit
init with the tag call.

Of course, I understand using “new” is the solution to be preferred always.
Just wanted to learn to know all the other behaviours as well.

Concerning the return value of the init I guess returning something
different than the object itself made sense from the time where init() had
to be always called explicitly (e.g. with createObject or and
<cfinvoke …>).
With an implicit call of course it doesn’t make sense.

I new tested with Railo 4.1.2 and Lucee 4.5.1 and indeed, it’s possible to
do nonsense like the following:
<cfset var test = new cfc.test(“foo”)>

where component cfc.test has:




and so the resulting content of var test is the string “foo” instead of the
object from “new cfc.test()”.

Hi Siegried,

The init() method will be implicitly called when using the ‘new’ syntax for
creating instances:

var myObjInstance = new myObj();

If you use CreateObject( ‘myObj’ ), the init() method is not called and
will need to be called manually, e.g.

var myObjInstance = CreateObject( ‘myObj’ ).init();

I would say that you should always return ‘this’ in the init() method, not
doing so will cause confusion at best and problems at worst. Though I’d be
curious to know what the reason for not returning ‘this’ is?

DominicOn 27 March 2015 at 10:20, Siegfried Wagner <@Siegfried_Wagner> wrote:

Hi,

I looked through existing discussions if I could find something to clarify
my question about how the init method in components is called with Lucee
but couldn’t find much.
Btw. I think there are a lot of discussions here not focusing on specific
topics but containing a total mixture of everything that comes to mind
(especially in threads about the “future of Lucee” ;-))

My questions: how are init methods of components called with Lucee? With
creation of the object?
How do you pass a parameter or pass a return value that is not the object
(=this)?

I’m a little bit confused because during my research on the topic, I saw
so many different interpretations of how the init method is called and the
parameters are processed through different ACF versions and where it is
called implicitly on creation and where not.

Thanks a lot for clarifying!
Siegfried


You received this message because you are subscribed to the Google Groups
“Lucee” group.
To unsubscribe from this group and stop receiving emails from it, send an
email to lucee+unsubscribe@googlegroups.com.
To post to this group, send email to lucee@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/lucee/d1b01e3a-13c9-4fd5-83bb-347f72a42fe1%40googlegroups.com
https://groups.google.com/d/msgid/lucee/d1b01e3a-13c9-4fd5-83bb-347f72a42fe1%40googlegroups.com?utm_medium=email&utm_source=footer
.
For more options, visit https://groups.google.com/d/optout.


Pixl8 Interactive, 3 Tun Yard, Peardon Street, London
SW8 3HT, United Kingdom

T: +44 [0] 845 260 0726• W: www.pixl8.co.uk• E: info@pixl8.co.uk
Follow us on: Facebook http://www.facebook.com/pixl8 Twitter
http://www.twitter.com/pixl8 LinkedIn
http://www.linkedin.com/pixl8CONFIDENTIAL
AND PRIVILEGED - This e-mail and any attachment is intended solely for the
addressee, is strictly confidential and may also be subject to legal,
professional or other privilege or may be protected by work product
immunity or other legal rules. If you are not the addressee please do not
read, print, re-transmit, store or act in reliance on it or any
attachments. Instead, please email it back to the sender and then
immediately permanently delete it. Pixl8 Interactive Ltd Registered in
England. Registered number: 04336501. Registered office: 8 Spur Road,
Cosham, Portsmouth, Hampshire, PO6 3EB

I would say that you should always return ‘this’ in the init() method, not
doing so will cause confusion at best and problems at worst. Though I’d be
curious to know what the reason for not returning ‘this’ is?

Note: at least on ColdFusion, it does not matter what you return from init(),
when it’s called implicitly (ie: via the new operator). The object itself
is always returned by new.

I cannot vouch for Lucee in this regard. It’s easy enough to test though.

That said, this is not to contradict what Dom says. In fact if anything it
concretes his position that one should always return this, so that explicit
calls to init() behave the same way as the implicit ones.On Friday, 27 March 2015 11:12:29 UTC, Dominic Watson wrote:


Adam

Just one thing to add, it is considered best practice now to write your
CFC’s in script so the example you gave would become something like:

component {
function init(string text) {
var localVar = arguments.text;
return localVar;
}
}

No tags required.

Kind regards,

Andrew
about.me http://about.me/andrew_dixon
mso http://www.mso.net - Lucee http://lucee.org - MemberOn 27 March 2015 at 14:51, Siegfried Wagner <@Siegfried_Wagner> wrote:

Hi,

thanks for the many replies so far.

I like the answer of Walter Seethaler very much because you show and
explain the differences very well. But also the others pointed out one very
important aspect I thought it would be different:
you say calling createObject() without expicitly calling init() does not
call the constructor (init)? I thought it’s always called implicitly in all
of todays ColdFusion servers including Railo and Lucee?

But it probably makes the most sense because if I see it correctly using
the tag variant with is identical to createObject, and that was
also part of my question, how one would provide parameters for the implicit
init with the tag call.

Of course, I understand using “new” is the solution to be preferred
always. Just wanted to learn to know all the other behaviours as well.

Concerning the return value of the init I guess returning something
different than the object itself made sense from the time where init() had
to be always called explicitly (e.g. with createObject or and
<cfinvoke …>).
With an implicit call of course it doesn’t make sense.

I new tested with Railo 4.1.2 and Lucee 4.5.1 and indeed, it’s possible to
do nonsense like the following:
<cfset var test = new cfc.test(“foo”)>

where component cfc.test has:




and so the resulting content of var test is the string “foo” instead of
the object from “new cfc.test()”.


You received this message because you are subscribed to the Google Groups
“Lucee” group.
To unsubscribe from this group and stop receiving emails from it, send an
email to lucee+unsubscribe@googlegroups.com.
To post to this group, send email to lucee@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/lucee/b04626ef-5457-46aa-846e-57dc3a0bfd27%40googlegroups.com
https://groups.google.com/d/msgid/lucee/b04626ef-5457-46aa-846e-57dc3a0bfd27%40googlegroups.com?utm_medium=email&utm_source=footer
.

For more options, visit https://groups.google.com/d/optout.

Depends on how you create your instances - new Foo(),
createObject(“componen”, "Foo).init(), <cfobject…> and <cfinvoke…> have
different behaviour. Which way do you use?

That’s kinda comparing apples to oranges to pears.

In your comparsion between createObject() and , with
createObject() you’re chaining a call to init(). If one was to remove the
explicit call to init(), do createObject() and differ?

And isn’t designed for creating objects, it’s designed for
executing methods. So not a valid comparison I think. That said, if you
call init() with , does it behave any different to
createObject().init() ?

The main reason is that CF was not designed as an OO language.

Well the bits of CFML you’re discussing here were designed to be OO. The
problem is that the design was a bit rubbish.On Friday, 27 March 2015 11:30:46 UTC, Walter Seethaler wrote:


Adam

that is actually not true, sorry.
When you have a component like this
component {
function init(){
return “susi”;
}
}

and a template with this
writedump(new Test());

you get the output “susi” and not the component in Lucee and ACF (10,11) .
In earlier version (Railo back then) was returning always the instance, but
for compatibility we changed this behaviour.
When thinking about it i have no clue why we did, because it is really
stupid.

MichaOn Fri, Mar 27, 2015 at 12:23 PM, Adam Cameron <@Adam_Cameron> wrote:

On Friday, 27 March 2015 11:12:29 UTC, Dominic Watson wrote:

I would say that you should always return ‘this’ in the init() method,
not doing so will cause confusion at best and problems at worst. Though I’d
be curious to know what the reason for not returning ‘this’ is?

Note: at least on ColdFusion, it does not matter what you return from
init(), when it’s called implicitly (ie: via the new operator). The
object itself is always returned by new.

I cannot vouch for Lucee in this regard. It’s easy enough to test though.

That said, this is not to contradict what Dom says. In fact if anything it
concretes his position that one should always return this, so that explicit
calls to init() behave the same way as the implicit ones.


Adam


You received this message because you are subscribed to the Google Groups
“Lucee” group.
To unsubscribe from this group and stop receiving emails from it, send an
email to lucee+unsubscribe@googlegroups.com.
To post to this group, send email to lucee@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/lucee/ae68639c-4081-400d-a597-9caa626d379e%40googlegroups.com
https://groups.google.com/d/msgid/lucee/ae68639c-4081-400d-a597-9caa626d379e%40googlegroups.com?utm_medium=email&utm_source=footer
.

For more options, visit https://groups.google.com/d/optout.

Depends on how you create your instances - new Foo(),
createObject(“componen”, "Foo).init(), <cfobject…> and <cfinvoke…> have
different behaviour. Which way do you use?

I would recommend new Foo(), because it best suits OO programming.

component{

variables.blah = "test";


function init(required numeric bar, array baz){
    variables.bar = bar;
    variables.bazlen = baz.len();  
    return THIS;  //required in Lucee - while ACF returns this if 

nothing else is returned
}

array function something(){}

}

The init method acts as constructor, everything outside of the functions
acts as *pseudo-constructor *(variables.blah=“test”).

new Foo( 1, [a,b,c] )

Creates the instance calls the pseudo-constructor and the *constructor *and
returns the instance.

createObject(“component”).init( 1, [a,b,c] );

Creates the instance calls the pseudo-constructor and the *constructor *and
returns the instance.

createObject(“component”);

Creates the instance calls the pseudo-constructor and returns the
instance.

Read the docs for cfobject
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7f6e.html
and cfinvoke
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7e0a.html.
These tags are old, I wouldn’t use them anymore.

component{

array function init(required numeric bar, array baz){
    return baz;
}

}

As the constructors in Lucee/ACF are no real constructors, but (almost)
normal methods, you can return what you want.
I think you shouldn’t use this - new Foo() should always return the
instance.

component{

*package* function init(required numeric bar, array baz){
    return this;
}

}

new other.package.Foo()

ACF: Throws an exception with the message: Can not access a package method
from outside…
Lucee (Bug): Creates the instance, calls the pseudo-constructor and
returns the instance.

component extends=“Bar” {

}

The Bar.init() method is inherited and called as described above.
If you implement the init-Method in Foo you have to call super.init()
manually.

In my opinion, the constructor behaviour is pretty obscure in CF. The main
reason is that CF was not designed as an OO language. I hope we can fix
this in the future.Am Freitag, 27. März 2015 11:20:58 UTC+1 schrieb Siegfried Wagner:

Hi,

I looked through existing discussions if I could find something to clarify
my question about how the init method in components is called with Lucee
but couldn’t find much.
Btw. I think there are a lot of discussions here not focusing on specific
topics but containing a total mixture of everything that comes to mind
(especially in threads about the “future of Lucee” ;-))

My questions: how are init methods of components called with Lucee? With
creation of the object?
How do you pass a parameter or pass a return value that is not the object
(=this)?

I’m a little bit confused because during my research on the topic, I saw
so many different interpretations of how the init method is called and the
parameters are processed through different ACF versions and where it is
called implicitly on creation and where not.

Thanks a lot for clarifying!
Siegfried

@Walter

could you raise a ticket about the following? Thanks in advance.
ACF: Throws an exception with the message: Can not access a package method
from outside…

Lucee (Bug): Creates the instance, calls the pseudo-constructor and
returns the instance.

MichaOn Fri, Mar 27, 2015 at 12:30 PM, Walter Seethaler <@Walter_Seethaler> wrote:

Depends on how you create your instances - new Foo(),
createObject(“componen”, "Foo).init(), <cfobject…> and <cfinvoke…> have
different behaviour. Which way do you use?

I would recommend new Foo(), because it best suits OO programming.

component{

variables.blah = "test";


function init(required numeric bar, array baz){
    variables.bar = bar;
    variables.bazlen = baz.len();
    return THIS;  //required in Lucee - while ACF returns this if

nothing else is returned
}

array function something(){}

}

The init method acts as constructor, everything outside of the
functions acts as *pseudo-constructor *(variables.blah=“test”).

new Foo( 1, [a,b,c] )

Creates the instance calls the pseudo-constructor and the *constructor *and
returns the instance.

createObject(“component”).init( 1, [a,b,c] );

Creates the instance calls the pseudo-constructor and the *constructor *and
returns the instance.

createObject(“component”);

Creates the instance calls the pseudo-constructor and returns the
instance.

Read the docs for cfobject
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7f6e.html
and cfinvoke
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7e0a.html.
These tags are old, I wouldn’t use them anymore.

component{

array function init(required numeric bar, array baz){
    return baz;
}

}

As the constructors in Lucee/ACF are no real constructors, but (almost)
normal methods, you can return what you want.
I think you shouldn’t use this - new Foo() should always return the
instance.

component{

*package* function init(required numeric bar, array baz){
    return this;
}

}

new other.package.Foo()

ACF: Throws an exception with the message: Can not access a package method
from outside…
Lucee (Bug): Creates the instance, calls the pseudo-constructor and
returns the instance.

component extends=“Bar” {

}

The Bar.init() method is inherited and called as described above.
If you implement the init-Method in Foo you have to call super.init()
manually.

In my opinion, the constructor behaviour is pretty obscure in CF. The main
reason is that CF was not designed as an OO language. I hope we can fix
this in the future.

Am Freitag, 27. März 2015 11:20:58 UTC+1 schrieb Siegfried Wagner:

Hi,

I looked through existing discussions if I could find something to
clarify my question about how the init method in components is called with
Lucee but couldn’t find much.
Btw. I think there are a lot of discussions here not focusing on specific
topics but containing a total mixture of everything that comes to mind
(especially in threads about the “future of Lucee” ;-))

My questions: how are init methods of components called with Lucee? With
creation of the object?
How do you pass a parameter or pass a return value that is not the object
(=this)?

I’m a little bit confused because during my research on the topic, I saw
so many different interpretations of how the init method is called and the
parameters are processed through different ACF versions and where it is
called implicitly on creation and where not.

Thanks a lot for clarifying!
Siegfried


You received this message because you are subscribed to the Google Groups
“Lucee” group.
To unsubscribe from this group and stop receiving emails from it, send an
email to lucee+unsubscribe@googlegroups.com.
To post to this group, send email to lucee@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/lucee/02a6e348-42c8-4217-bc9a-85539315ee7a%40googlegroups.com
https://groups.google.com/d/msgid/lucee/02a6e348-42c8-4217-bc9a-85539315ee7a%40googlegroups.com?utm_medium=email&utm_source=footer
.

For more options, visit https://groups.google.com/d/optout.

done

https://bitbucket.org/lucee/lucee/issue/242/package-init-doesnt-work-correctAm Freitag, 27. März 2015 18:50:31 UTC+1 schrieb Micha:

@Walter

could you raise a ticket about the following? Thanks in advance.
ACF: Throws an exception with the message: Can not access a package
method from outside…

Lucee (Bug): Creates the instance, calls the pseudo-constructor and
returns the instance.

Micha

On Fri, Mar 27, 2015 at 12:30 PM, Walter Seethaler <seet...@nbsp.com <javascript:>> wrote:

Depends on how you create your instances - new Foo(),
createObject(“componen”, "Foo).init(), <cfobject…> and <cfinvoke…> have
different behaviour. Which way do you use?

I would recommend new Foo(), because it best suits OO programming.

component{

variables.blah = "test";


function init(required numeric bar, array baz){
    variables.bar = bar;
    variables.bazlen = baz.len();  
    return THIS;  //required in Lucee - while ACF returns this if 

nothing else is returned
}

array function something(){}

}

The init method acts as constructor, everything outside of the
functions acts as *pseudo-constructor *(variables.blah=“test”).

new Foo( 1, [a,b,c] )

Creates the instance calls the pseudo-constructor and the
*constructor *and returns the instance.

createObject(“component”).init( 1, [a,b,c] );

Creates the instance calls the pseudo-constructor and the
*constructor *and returns the instance.

createObject(“component”);

Creates the instance calls the pseudo-constructor and returns the
instance.

Read the docs for cfobject
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7f6e.html
and cfinvoke
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7e0a.html.
These tags are old, I wouldn’t use them anymore.

component{

array function init(required numeric bar, array baz){
    return baz;
}

}

As the constructors in Lucee/ACF are no real constructors, but (almost)
normal methods, you can return what you want.
I think you shouldn’t use this - new Foo() should always return the
instance.

component{

*package* function init(required numeric bar, array baz){
    return this;
}

}

new other.package.Foo()

ACF: Throws an exception with the message: Can not access a package
method from outside…
Lucee (Bug): Creates the instance, calls the pseudo-constructor and
returns the instance.

component extends=“Bar” {

}

The Bar.init() method is inherited and called as described above.
If you implement the init-Method in Foo you have to call super.init()
manually.

In my opinion, the constructor behaviour is pretty obscure in CF. The
main reason is that CF was not designed as an OO language. I hope we can
fix this in the future.

Am Freitag, 27. März 2015 11:20:58 UTC+1 schrieb Siegfried Wagner:

Hi,

I looked through existing discussions if I could find something to
clarify my question about how the init method in components is called with
Lucee but couldn’t find much.
Btw. I think there are a lot of discussions here not focusing on
specific topics but containing a total mixture of everything that comes to
mind (especially in threads about the “future of Lucee” ;-))

My questions: how are init methods of components called with Lucee? With
creation of the object?
How do you pass a parameter or pass a return value that is not the
object (=this)?

I’m a little bit confused because during my research on the topic, I saw
so many different interpretations of how the init method is called and the
parameters are processed through different ACF versions and where it is
called implicitly on creation and where not.

Thanks a lot for clarifying!
Siegfried


You received this message because you are subscribed to the Google Groups
“Lucee” group.
To unsubscribe from this group and stop receiving emails from it, send an
email to lucee+un...@googlegroups.com <javascript:>.
To post to this group, send email to lu...@googlegroups.com <javascript:>
.
To view this discussion on the web visit
https://groups.google.com/d/msgid/lucee/02a6e348-42c8-4217-bc9a-85539315ee7a%40googlegroups.com
https://groups.google.com/d/msgid/lucee/02a6e348-42c8-4217-bc9a-85539315ee7a%40googlegroups.com?utm_medium=email&utm_source=footer
.

For more options, visit https://groups.google.com/d/optout.

Depends on how you create your instances - new Foo(),
createObject(“componen”, "Foo).init(), <cfobject…> and <cfinvoke…> have
different behaviour. Which way do you use?

That’s kinda comparing apples to oranges to pears.

In your comparsion between createObject() and , with
createObject() you’re chaining a call to init(). If one was to remove the
explicit call to init(), do createObject() and differ?

And isn’t designed for creating objects, it’s designed for
executing methods. So not a valid comparison I think. That said, if you
call init() with , does it behave any different to
createObject().init() ?

Sry Adam, I haven’t used cfobject or cfinvoke for years and almost
forgotten how they work. So I just wanted to provide a link to the docs for
Siegfried and compare new with createObject. But you are obviously right
with cfobject. Cfinvoke probably behaves like createObject, but you should
use it with the returnVariable attribute or you end up creating new
instances on every method call.

The main reason is that CF was not designed as an OO language.

Well the bits of CFML you’re discussing here were designed to be OO.
The problem is that the design was a bit rubbish.

Well, it depends how you define “was designed”. Since CF9 added the new
operator, the init method became a kind of constructor (calls the method
and returns the instance if nothing else is returned). But the only thing
that was designed here is the new operator, but not the language.> On Friday, 27 March 2015 11:30:46 UTC, Walter Seethaler wrote: