Что такое статическая версия метода propertyMissing в Groovy?
Хорошо - пробовал искать / читать и не уверен, что у меня есть ответ на это.
У меня есть класс Utility, который внутренне оборачивает статический ConcurrentLinkedQueue.
Утилита сама по себе добавляет некоторые статические методы - я не ожидаю вызова new для создания экземпляра Утилиты.
Я хочу перехватить вызовы getProperty служебного класса - и реализовать их внутренне в определении класса
Я могу добиться этого, добавив следующее в метакласс служебных классов, прежде чем использовать его
UnitOfMeasure.metaClass.static.propertyMissing = {name -> println "accessed prop called $name"}
println UnitOfMeasure.'Each'
однако, что я хочу сделать, это объявить перехват в самом определении класса. я попробовал это в определении класса - но, кажется, его никогда не вызывают
static def propertyMissing (receiver, String propName) {
println "prop $propName, saught"
}
я тоже пытался
static def getProperty (String prop) { println "доступ к $prop"}
но это тоже не называется.
Таким образом, кроме добавления в metaClass в моем коде / скрипте перед использованием, как можно объявить в служебном классе, который хочет захватить доступ к свойству
фактический класс у меня выглядит так в настоящее время
class UnitOfMeasure {
static ConcurrentLinkedQueue UoMList = new ConcurrentLinkedQueue(["Each", "Per Month", "Days", "Months", "Years", "Hours", "Minutes", "Seconds" ])
String uom
UnitOfMeasure () {
if (!UoMList.contains(this) )
UoMList << this
}
static list () {
UoMList.toArray()
}
static getAt (index) {
def value = null
if (index in 0..(UoMList.size() -1))
value = UoMList[index]
else if (index instanceof String) {
Closure matchClosure = {it.toUpperCase().contains(index.toUpperCase())}
def position = UoMList.findIndexOf (matchClosure)
if (position != -1)
value = UoMList[position]
}
value
}
static def propertyMissing (receiver, String propName) {
println "prop $propName, saught"
}
//expects either a String or your own closure, with String will do case insensitive find
static find (match) {
Closure matchClosure
if (match instanceof Closure)
matchClosure = match
if (match instanceof String) {
matchClosure = {it.toUpperCase().contains(match.toUpperCase())}
}
def inlist = UoMList.find (matchClosure)
}
static findWithIndex (match) {
Closure matchClosure
if (match instanceof Closure)
matchClosure = match
else if (match instanceof String) {
matchClosure = {it.toUpperCase().contains(match.toUpperCase())}
}
def position = UoMList.findIndexOf (matchClosure)
position != -1 ? [UoMList[position], position] : ["Not In List", -1]
}
}
Я был бы признателен за то, чтобы сделать это для статического служебного класса, а не для перехвата свойств на уровне экземпляра, и сделать это в объявлении класса - не добавляя в metaClass до того, как я сделаю вызовы.
просто чтобы вы могли видеть реальный класс и скрипт, который вызывает - я прикрепил их ниже
мой сценарий, который вызывает класс выглядит следующим образом
println UnitOfMeasure.list()
def (uom, position) = UnitOfMeasure.findWithIndex ("Day")
println "$uom at postition $position"
// works UnitOfMeasure.metaClass.static.propertyMissing = {name -> println "accessed prop called $name"}
println UnitOfMeasure[4]
println UnitOfMeasure.'Per'
какие ошибки как это
[Each, Per Month, Days, Months, Years, Hours, Minutes, Seconds]
Days at postition 2
Years
Caught: groovy.lang.MissingPropertyException: No such property: Per for class: com.softwood.portfolio.UnitOfMeasure
Possible solutions: uom
groovy.lang.MissingPropertyException: No such property: Per for class: com.softwood.portfolio.UnitOfMeasure
Possible solutions: uom
at com.softwood.scripts.UoMTest.run(UoMTest.groovy:12)
1 ответ
Статическая версия propertyMissing
метод называется $static_propertyMissing
:
static def $static_propertyMissing(String name) {
// do something
}
Этот метод вызывается MetaClassImpl
в строке 1002:
protected static final String STATIC_METHOD_MISSING = "$static_methodMissing";
protected static final String STATIC_PROPERTY_MISSING = "$static_propertyMissing";
// ...
protected Object invokeStaticMissingProperty(Object instance, String propertyName, Object optionalValue, boolean isGetter) {
MetaClass mc = instance instanceof Class ? registry.getMetaClass((Class) instance) : this;
if (isGetter) {
MetaMethod propertyMissing = mc.getMetaMethod(STATIC_PROPERTY_MISSING, GETTER_MISSING_ARGS);
if (propertyMissing != null) {
return propertyMissing.invoke(instance, new Object[]{propertyName});
}
} else {
// .....
}
// ....
}
Пример:
class Hello {
static def $static_propertyMissing(String name) {
println "Hello, $name!"
}
}
Hello.World
Выход:
Hello, World!