////
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
////

A taglib can be used in a GSP as an ordinary tag, or it might be used as a function in other taglibs or GSP expressions.

Internally Grails intercepts calls to tag handlers (method-based or closure-based).
The "out" that is available in a taglib is mapped to a `java.io.Writer` implementation that writes to a buffer
that "captures" the output of the taglib call. This buffer is the return value of a tag library call when it's
used as a function.

If the tag is listed in the library's static `returnObjectForTags` array, then its return value will be written to
the output when it's used as a normal tag. The return value of the tag method/closure will be returned as-is
if it's used as a function in GSP expressions or other taglibs.

If the tag is not included in the returnObjectForTags array, then its return value will be discarded.
Using "out" to write output in returnObjectForTags is not supported.

Example:
[source,groovy]
----
class ObjectReturningTagLib {
    static namespace = "cms"
    static returnObjectForTags = ['content']

    def content(Map attrs) {
        CmsContent.findByCode(attrs.code)?.content
    }
}
----

Given this example `cms.content(code: 'something')` call in another taglib or GSP expression would return the value `CmsContent.content` directly to the caller without
wrapping the return value in a buffer. It might be worth doing so also because of performance optimization reasons. There is no need to wrap the
tag return value in an output buffer in such cases.
