[prev in list] [next in list] [prev in thread] [next in thread] 

List:       groovy-user
Subject:    Re: [groovy-user] @TupleConstructor together with @TupleConstructor
From:       Pavel Alexeev <forum () hubbitus ! com ! ru>
Date:       2014-09-24 13:19:43
Message-ID: 5422C4EF.8000901 () hubbitus ! info
[Download RAW message or body]

Ok. I think it will be good start from beginning.
I want use use Objects for some policy or configuration. Off course I
known about great ConfigSlurper but I want it be typed and checked, so
provide some interface in form of class. For some configuration options
I allow provide closures, but want it act only in context
Closure.DELEGATE_ONLY.

Unfortunately we can't mix groovy map-style object creation and
anonymous class creation for methods override. So I'm stick with
closures as fields (properties). For example:
class Policy{
    URL source;
    File dest;
    def content;

    Closure load = { content = source.text }
    Closure process = {  }
    Closure<Boolean> save = { dest.write(content) }
}

Configuration for many cases will be written only for thus parts which
should have different from default behavior, like:
new Policy(
    source: new URL('http://google.com')
    ,dest: new File('place.there')
    ,process: { content.replaceAll(…) }
)

I want to closures will access defined in object fields (like content in
example before). Some fields also injected later in runtime (like named
logging). For that I need always set for new closures delegate to owner
object transparently. For that was shown before constructor with Map
argument. I also plan implement several kind of such sub Policies like:
class PolicyA extends Policy{…}
so copy/paste of that constructor implementation is bad solution.
Traits can't contain constructors.

Unfortunately due to the http://jira.codehaus.org/browse/GROOVY-7087
(@TupleConstructor does not call setters ) I realize I can't use it too now.

So now I look at overriding setProperty method.

24.09.2014 15:44, Paul King wrote:
>
> Thanks, that helps a bit. I guess I am still not sure what you are
> trying to do with the Map constructor in Base. Isn't the default
> behavior good enough?
>
> import groovy.transform.*
>
> class Base{ }
>
> @TupleConstructor(includeFields=true)
> @ToString(includeNames=true, includeFields=true)
> class Person extends Base{
>     String name
>     public Integer age
> }
>
> println Person.constructors
> [ new Person(name: 'Pavel', age: 100), new Person('Pavel1', 200) ]
>
> I presume there is something additional you want to do but I am unsure
> what?
>
> Cheers, Paul.
>
> On 24/09/2014 8:18 PM, Pavel Alexeev wrote:
>> Hi Paul.
>> Thank you for the answer.
>> Obviously in my first example was mistake.
>> Person p = new Person(['UserName', 33]);
>> should be:
>> Person p = new Person(name: 'UserName', age: 33]);
>>
>> Ok, another example:
>>
>> class Base{
>>      //!!! Without defining that constructor:
>> java.lang.NoSuchMethodError: Base: method <init>()V not found
>>      //Base(){ println "Called Base()" }
>>
>>      Base(Map map){
>>          println "Called Base(Map map)"
>>          for (entry in map) {
>>              if (entry.value instanceof Closure){
>>                  ((Closure)entry.value).delegate = this;
>>                  ((Closure)entry.value).resolveStrategy =
>> Closure.DELEGATE_ONLY;
>>              }
>>              this."${entry.key}" = entry.value;
>>          }
>>      }
>> }
>>
>> @TupleConstructor(force=true, includeFields=true)
>> @ToString(includeNames=true, includeFields=true)
>> class Person extends Base{
>>      String name
>>      public Integer age
>> }
>>
>> println Person.constructors
>> [ new Person(name: 'Pavel', age: 100), new Person('Pavel1', 200) ]
>>
>> I got:
>> [public Person(), public Person(java.lang.String), public
>> Person(java.lang.String,java.lang.Integer)]
>> Exception thrown
>> java.lang.NoSuchMethodError: Base: method <init>()V not found
>>
>> So "public Person()" defined is it really required explicitly define
>> Base() constructor too?
>>
>> 24.09.2014 00:20, Paul King wrote:
>>>
>>> You don't have a List constructor so the NoSuchMethodError seems
>>> appropriate.
>>> In terms of giving you advice on what you should have I am not sure
>>> there is
>>> enough info in your example? Is "map" a property of Base?  Perhaps you
>>> could
>>> elaborate just a little more?
>>>
>>> Cheers, Paul.
>>>
>>> On 24/09/2014 3:40 AM, Pavel Alexeev wrote:
>>>> Hello.
>>>>
>>>> I'he try use two annotations but seams not fully understand logic. I
>>>> want copy constructors (one really) from parent, and generate
>>>> others by
>>>> fields of class:
>>>>
>>>> class Base{
>>>>       Base(Map map){
>>>>           println "Called Base(Map map)"
>>>>       }
>>>> }
>>>>
>>>> @TupleConstructor(force=true)
>>>> @InheritConstructors
>>>> class Person extends Base{
>>>>       def firstName
>>>>       def age
>>>> }
>>>>
>>>> println Person.constructors
>>>>
>>>> It give me output:
>>>> [public Person(java.util.Map), public Person(java.lang.Object), public
>>>> Person(java.lang.Object,java.lang.Object), public Person()]
>>>>
>>>> But on instantiate of object:
>>>> Person p = new Person(['UserName', 33]);
>>>> got exception:
>>>> java.lang.NoSuchMethodError: Base: method <init>()V not found
>>>>
>>>> What also looks reasonable (meantime note I call constructor with
>>>> parameters).
>>>> Adding empty constructor like Base(){} also thrown error:
>>>> java.lang.ClassFormatError: Duplicate method name&signature in class
>>>> file Person
>>>> Indeed empty constructor already was generated as we seen early.
>>>>
>>>> Is there way pick up what exactly constructor I would like to copy? Or
>>>> any other suggestions please.
>>>>
>>>
>>>
>>> ---
>>> This email is free from viruses and malware because avast! Antivirus
>>> protection is active.
>>> http://www.avast.com
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe from this list, please visit:
>>>
>>>     http://xircles.codehaus.org/manage_email
>>>
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe from this list, please visit:
>>
>>      http://xircles.codehaus.org/manage_email
>>
>>
>>
>
>
> ---
> This email is free from viruses and malware because avast! Antivirus
> protection is active.
> http://www.avast.com
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>


[Attachment #3 (text/html)]

<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">Ok. I think it will be good start from
      beginning.<br>
      I want use use Objects for some policy or configuration. Off
      course I known about great ConfigSlurper but I want it be typed
      and checked, so provide some interface in form of class. For some
      configuration options I allow provide closures, but want it act
      only in context Closure.DELEGATE_ONLY.<br>
      <br>
      Unfortunately we can't mix groovy map-style object creation and
      anonymous class creation for methods override. So I'm stick with
      closures as fields (properties). For example:<br>
      class Policy{<br>
          URL source;<br>
          File dest;<br>
          def content;<br>
      <br>
          Closure load = { content = source.text }<br>
          Closure process = {  }<br>
          Closure&lt;Boolean&gt; save = { dest.write(content) }<br>
      }<br>
      <br>
      Configuration for many cases will be written only for thus parts
      which should have different from default behavior, like:<br>
      new Policy(<br>
          source: new URL('<a class="moz-txt-link-freetext" \
href="http://google.com">http://google.com</a>')<br>  ,dest: new \
File('place.there')<br>  ,process: { content.replaceAll(…) }<br>
      )<br>
      <br>
      I want to closures will access defined in object fields (like
      content in example before). Some fields also injected later in
      runtime (like named logging). For that I need always set for new
      closures delegate to owner object transparently. For that was
      shown before constructor with Map argument. I also plan implement
      several kind of such sub Policies like:<br>
      class PolicyA extends Policy{…}<br>
      so copy/paste of that constructor implementation is bad solution.<br>
      Traits can't contain constructors.<br>
      <br>
      Unfortunately due to the
      <a class="moz-txt-link-freetext" \
href="http://jira.codehaus.org/browse/GROOVY-7087">http://jira.codehaus.org/browse/GROOVY-7087</a> \
(@TupleConstructor  does not call setters
      <meta http-equiv="content-type" content="text/html; charset=utf-8">
      ) I realize I can't use it too now.<br>
      <br>
      So now I look at overriding setProperty method.<br>
      <br>
      24.09.2014 15:44, Paul King wrote:<br>
    </div>
    <blockquote cite="mid:5422AE89.2080005@asert.com.au" type="cite">
      <br>
      Thanks, that helps a bit. I guess I am still not sure what you are
      trying to do with the Map constructor in Base. Isn't the default
      behavior good enough?
      <br>
      <br>
      import groovy.transform.*
      <br>
      <br>
      class Base{ }
      <br>
      <br>
      @TupleConstructor(includeFields=true)
      <br>
      @ToString(includeNames=true, includeFields=true)
      <br>
      class Person extends Base{
      <br>
          String name
      <br>
          public Integer age
      <br>
      }
      <br>
      <br>
      println Person.constructors
      <br>
      [ new Person(name: 'Pavel', age: 100), new Person('Pavel1', 200) ]
      <br>
      <br>
      I presume there is something additional you want to do but I am
      unsure what?
      <br>
      <br>
      Cheers, Paul.
      <br>
      <br>
      On 24/09/2014 8:18 PM, Pavel Alexeev wrote:
      <br>
      <blockquote type="cite">Hi Paul.
        <br>
        Thank you for the answer.
        <br>
        Obviously in my first example was mistake.
        <br>
        Person p = new Person(['UserName', 33]);
        <br>
        should be:
        <br>
        Person p = new Person(name: 'UserName', age: 33]);
        <br>
        <br>
        Ok, another example:
        <br>
        <br>
        class Base{
        <br>
             //!!! Without defining that constructor:
        <br>
        java.lang.NoSuchMethodError: Base: method &lt;init&gt;()V not
        found
        <br>
             //Base(){ println "Called Base()" }
        <br>
        <br>
             Base(Map map){
        <br>
                 println "Called Base(Map map)"
        <br>
                 for (entry in map) {
        <br>
                     if (entry.value instanceof Closure){
        <br>
                         ((Closure)entry.value).delegate = this;
        <br>
                         ((Closure)entry.value).resolveStrategy =
        <br>
        Closure.DELEGATE_ONLY;
        <br>
                     }
        <br>
                     this."${entry.key}" = entry.value;
        <br>
                 }
        <br>
             }
        <br>
        }
        <br>
        <br>
        @TupleConstructor(force=true, includeFields=true)
        <br>
        @ToString(includeNames=true, includeFields=true)
        <br>
        class Person extends Base{
        <br>
             String name
        <br>
             public Integer age
        <br>
        }
        <br>
        <br>
        println Person.constructors
        <br>
        [ new Person(name: 'Pavel', age: 100), new Person('Pavel1', 200)
        ]
        <br>
        <br>
        I got:
        <br>
        [public Person(), public Person(java.lang.String), public
        <br>
        Person(java.lang.String,java.lang.Integer)]
        <br>
        Exception thrown
        <br>
        java.lang.NoSuchMethodError: Base: method &lt;init&gt;()V not
        found
        <br>
        <br>
        So "public Person()" defined is it really required explicitly
        define
        <br>
        Base() constructor too?
        <br>
        <br>
        24.09.2014 00:20, Paul King wrote:
        <br>
        <blockquote type="cite">
          <br>
          You don't have a List constructor so the NoSuchMethodError
          seems
          <br>
          appropriate.
          <br>
          In terms of giving you advice on what you should have I am not
          sure
          <br>
          there is
          <br>
          enough info in your example? Is "map" a property of Base? 
          Perhaps you
          <br>
          could
          <br>
          elaborate just a little more?
          <br>
          <br>
          Cheers, Paul.
          <br>
          <br>
          On 24/09/2014 3:40 AM, Pavel Alexeev wrote:
          <br>
          <blockquote type="cite">Hello.
            <br>
            <br>
            I'he try use two annotations but seams not fully understand
            logic. I
            <br>
            want copy constructors (one really) from parent, and
            generate others by
            <br>
            fields of class:
            <br>
            <br>
            class Base{
            <br>
                  Base(Map map){
            <br>
                      println "Called Base(Map map)"
            <br>
                  }
            <br>
            }
            <br>
            <br>
            @TupleConstructor(force=true)
            <br>
            @InheritConstructors
            <br>
            class Person extends Base{
            <br>
                  def firstName
            <br>
                  def age
            <br>
            }
            <br>
            <br>
            println Person.constructors
            <br>
            <br>
            It give me output:
            <br>
            [public Person(java.util.Map), public
            Person(java.lang.Object), public
            <br>
            Person(java.lang.Object,java.lang.Object), public Person()]
            <br>
            <br>
            But on instantiate of object:
            <br>
            Person p = new Person(['UserName', 33]);
            <br>
            got exception:
            <br>
            java.lang.NoSuchMethodError: Base: method &lt;init&gt;()V
            not found
            <br>
            <br>
            What also looks reasonable (meantime note I call constructor
            with
            <br>
            parameters).
            <br>
            Adding empty constructor like Base(){} also thrown error:
            <br>
            java.lang.ClassFormatError: Duplicate method
            name&amp;signature in class
            <br>
            file Person
            <br>
            Indeed empty constructor already was generated as we seen
            early.
            <br>
            <br>
            Is there way pick up what exactly constructor I would like
            to copy? Or
            <br>
            any other suggestions please.
            <br>
            <br>
          </blockquote>
          <br>
          <br>
          ---
          <br>
          This email is free from viruses and malware because avast!
          Antivirus
          <br>
          protection is active.
          <br>
          <a class="moz-txt-link-freetext" \
href="http://www.avast.com">http://www.avast.com</a>  <br>
          <br>
          <br>
---------------------------------------------------------------------
          <br>
          To unsubscribe from this list, please visit:
          <br>
          <br>
              <a class="moz-txt-link-freetext" \
href="http://xircles.codehaus.org/manage_email">http://xircles.codehaus.org/manage_email</a>
  <br>
          <br>
          <br>
        </blockquote>
        <br>
        <br>
---------------------------------------------------------------------
        <br>
        To unsubscribe from this list, please visit:
        <br>
        <br>
             <a class="moz-txt-link-freetext" \
href="http://xircles.codehaus.org/manage_email">http://xircles.codehaus.org/manage_email</a>
  <br>
        <br>
        <br>
        <br>
      </blockquote>
      <br>
      <br>
      ---
      <br>
      This email is free from viruses and malware because avast!
      Antivirus protection is active.
      <br>
      <a class="moz-txt-link-freetext" \
href="http://www.avast.com">http://www.avast.com</a>  <br>
      <br>
      <br>
---------------------------------------------------------------------
      <br>
      To unsubscribe from this list, please visit:
      <br>
      <br>
         <a class="moz-txt-link-freetext" \
href="http://xircles.codehaus.org/manage_email">http://xircles.codehaus.org/manage_email</a>
  <br>
      <br>
      <br>
    </blockquote>
    <br>
  </body>
</html>



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic