<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-201222784399701120</id><updated>2011-07-29T03:21:40.115+10:00</updated><title type='text'>Winy. Groovy</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://vinfin-on-groovy.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/201222784399701120/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://vinfin-on-groovy.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Anton</name><uri>http://www.blogger.com/profile/13048203907330644097</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>2</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-201222784399701120.post-7958819240637282768</id><published>2010-04-27T10:34:00.006+10:00</published><updated>2010-04-27T10:39:31.568+10:00</updated><title type='text'></title><content type='html'>&lt;blockquote&gt;The Ruby collection classes (Array, Hash, and so on) support a large number of operations that do various things with the collection: traverse it, sort it, and so on. You may be thinking, “Gee, it’d sure be nice if my class could support all these neat-o features, too!” (If you actually thought that, it’s probably time to stop watching reruns of 1960s television shows.)&lt;/blockquote&gt;&lt;br /&gt;&lt;div style="text-align:right"&gt;Programming Ruby 1.9&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/201222784399701120-7958819240637282768?l=vinfin-on-groovy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vinfin-on-groovy.blogspot.com/feeds/7958819240637282768/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=201222784399701120&amp;postID=7958819240637282768' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/201222784399701120/posts/default/7958819240637282768'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/201222784399701120/posts/default/7958819240637282768'/><link rel='alternate' type='text/html' href='http://vinfin-on-groovy.blogspot.com/2010/04/ruby-collection-classes-array-hash-and.html' title=''/><author><name>Anton</name><uri>http://www.blogger.com/profile/18349117462307426076</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-201222784399701120.post-944879321808983926</id><published>2008-04-05T16:31:00.026+11:00</published><updated>2008-08-04T22:02:21.329+10:00</updated><title type='text'>Groovy Fields and Properties</title><content type='html'>После прочтения раздела Java and Groovy Integration книги Groovy Recipes, мне стало очень интересно, что же там скрывается за private и public свойствами в Groovy.&lt;br /&gt;&lt;h2&gt;Suppressing Getter/Setter Generation&lt;/h2&gt;&lt;br /&gt;В Groovy есть два модификатора: private и public. Поэтому я могу написать&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class Bla {&lt;div style="margin-left:20px"&gt;def a = 3&lt;br /&gt;private b = 3&lt;br /&gt;public c = 3&lt;br /&gt;&lt;/div&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;В первом случае модификатор не указан явно, в остальных – указан. В результате, если вывести&lt;br /&gt;&lt;code&gt;['a', 'b', 'c'].each {&lt;div style="margin-left:20px"&gt;println Bla.getDeclaredField(it)&lt;/div&gt;}&lt;/code&gt;&lt;br /&gt;то для этих трех случаев мы получим&lt;br /&gt;&lt;code&gt;&amp;gt; private java.lang.Object Bla.a&lt;br /&gt;&amp;gt; private java.lang.Object Bla.b&lt;br /&gt;&amp;gt; public java.lang.Object Bla.c&lt;/code&gt;&lt;br /&gt;Действительно, если не указано явно, то поле будет иметь модификтор private.&lt;br /&gt;Автор книги пишет, что делает явное объявление поля как private: &lt;br /&gt;&lt;blockquote&gt;Explicitly flagging a field as private in Groovy suppresses the creation of the corresponding getter and setter methods.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Действительно:&lt;br /&gt;&lt;code&gt;class Bla {&lt;div style="margin-left:20px"&gt;private a = 3&lt;/div&gt;}&lt;/code&gt;&lt;br /&gt;&lt;code&gt;println bla.invokeMethod('getA', null)&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;gt; Caught: groovy.lang.MissingMethodException: No signature of method: Bla.getA() is applicable for argument types: () values: {}&lt;/code&gt;&lt;br /&gt;В то время как&lt;br /&gt;&lt;code&gt;class Bla {&lt;div style="margin-left:20px"&gt;def a = 3&lt;/div&gt;}&lt;/code&gt;&lt;br /&gt;&lt;code&gt;println bla.invokeMethod('getA', null)&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;gt; 3&lt;/code&gt;&lt;br /&gt;С другой стороны, следующий пример должен заставить задуматься:&lt;br /&gt;&lt;code&gt;class Bla {&lt;div style="margin-left:20px"&gt;public a = 3&lt;/div&gt;}&lt;/code&gt;&lt;br /&gt;&lt;code&gt;println bla.invokeMethod('getA', null)&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;gt; Caught: groovy.lang.MissingMethodException: No signature of method: Bla.getA() is applicable for argument types: () values: {}&lt;/code&gt;&lt;br /&gt;Т.е. не только private, но и public подавляет автогенерацию get и set методов. Хотя, конечно, ничто не мешает нам определить их самим. Мне непонятно, зачем же нужны два противоположных модификатора, которые, судя по всему, приводят к одинаковому результату. Возможно, это касается только интеграции с Java.&lt;br /&gt;&lt;h2&gt;getProperties()&lt;/h2&gt;&lt;br /&gt;Этот метод возвращает список доступных свойств объекта. Судя по всему, этот список формируется по всем имеющимся get методам и значениям, которые они возвращают. Например:&lt;br /&gt;&lt;code&gt;class Bla {&lt;div style="margin-left:20px"&gt;public a = 3&lt;br /&gt;def getA() {&lt;div style="margin-left:20px"&gt;return a + 10&lt;/div&gt;}&lt;br /&gt;def getB() {&lt;div style="margin-left:20px"&gt;return 33&lt;/div&gt;}&lt;br /&gt;&lt;/div&gt;}&lt;/code&gt;&lt;br /&gt;&lt;code&gt;println bla.getProperties()&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;gt; ["metaClass":groovy.lang.MetaClassImpl@1f78ef1[class Bla], "class":class Bla, "b":33, "a":13]&lt;/code&gt;&lt;br /&gt;&lt;h2&gt;Как происходит обращение к свойству извне и изнутри&lt;/h2&gt;&lt;br /&gt;О том, как происходит обращение к свойству, довелось узнать не из книг по Groovy, а проведя несколько минут с дебаггером, переопределяя методы и ставя в них брейкпоинты. Вот что получилось, или "о том, что будет, если я сделаю вот так":&lt;br /&gt;&lt;code&gt;println bla.foo&lt;/code&gt;&lt;br /&gt;или&lt;br /&gt;&lt;code&gt;bla.foo = 147&lt;/code&gt;&lt;br /&gt;В первом случае происходит обращение к getProperty(String name), который пытается найти метод getFoo(String name). Этот метод должен присутствовать, он не должен быть синтезирован - invokeMethod(String name, args) и methodMissing(String name, args) не используются, и синтезированный метод не будет найден. Если метод найден, на его вызове все заканчивается. Если нет – будет произведена попытка найти поле с именем foo, и получить его значение (эквивалент bla.@foo). Если поле не найдено, вызывается метод propertyMissing(String name), который, в стандартной реализации, выбрасывает groovy.lang.MissingPropertyException.&lt;br /&gt;&lt;br /&gt;Во втором случае – все аналогично, только сигнатуры методов выглядят как void setProperty(String name, args), void setFoo(String name, args), void propertyMissing(String name, value). setFoo(String name, value) тоже должен присутствовать или быть инъектированным. propertyMissing(String name, value) также по умолчанию выбрасывает исключение groovy.lang.MissingPropertyException. И еще – в этом случае все методы определены с типом void, а метод void propertyMissing(String name, value) получает значения, которое нужно присвоить. &lt;br /&gt;&lt;br /&gt;Если обращение производится из самого объекта, например, a или this.a то сначала – попытка обратиться к полю напрямую (эквивалент this.@a), затем – вызов getProperty(String name) или void setProperty(String name, value), как уже было описано. Т.е. внутри объекта – обращение к полю более приоритетно, чем к свойству.&lt;br /&gt;И еще немного юмора.&lt;br /&gt;&lt;code&gt;class Bla {&lt;div style="margin-left:20px"&gt;def A = 'A'&lt;br /&gt;def getA() {&lt;div style="margin-left:20px"&gt;return 'small a'&lt;/div&gt;}&lt;br /&gt;&lt;/div&gt;}&lt;/code&gt;&lt;br /&gt;&lt;code&gt;println bla.getProperties()&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;gt; ["metaClass":groovy.lang.MetaClassImpl@2a4983[class Bla], "class":class Bla, "a":"small a"]&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/201222784399701120-944879321808983926?l=vinfin-on-groovy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vinfin-on-groovy.blogspot.com/feeds/944879321808983926/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=201222784399701120&amp;postID=944879321808983926' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/201222784399701120/posts/default/944879321808983926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/201222784399701120/posts/default/944879321808983926'/><link rel='alternate' type='text/html' href='http://vinfin-on-groovy.blogspot.com/2008/04/java-and-groovy-integration-groovy.html' title='Groovy Fields and Properties'/><author><name>Anton</name><uri>http://www.blogger.com/profile/13048203907330644097</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
