2013-06-21 8 views
10

my previous question के उत्तरों के लिए धन्यवाद, मैं एक फ़ंक्शन मैक्रो बनाने में सक्षम था जैसे कि यह Map देता है जो प्रत्येक फ़ील्ड नाम को कक्षा के मान के लिए मानचित्र करता है, उदा।स्कैला मैक्रोज़: एक निश्चित एनोटेशन के लिए जांच

... 

trait Model 

case class User (name: String, age: Int, posts: List[String]) extends Model { 
    val numPosts: Int = posts.length 

    ... 

    def foo = "bar" 

    ... 
} 

तो इस आदेश

val myUser = User("Foo", 25, List("Lorem", "Ipsum")) 

myUser.asMap 

रिटर्न

Map("name" -> "Foo", "age" -> 25, "posts" -> List("Lorem", "Ipsum"), "numPosts" -> 2) 

यह वह जगह है जहां Map के लिए Tuple रों उत्पन्न कर रहे हैं (देखें ट्रैविस ब्राउन के answer):

... 

val pairs = weakTypeOf[T].declarations.collect { 
    case m: MethodSymbol if m.isAccessor => 
    val name = c.literal(m.name.decoded) 
    val value = c.Expr(Select(model, m.name)) 
    reify(name.splice -> value.splice).tree 
} 

... 

अब मैं उन क्षेत्रों को अनदेखा करना चाहता हूं जिनमें @transient एनोटेशन है। मैं कैसे जांच करूं कि किसी विधि में @transient एनोटेशन है?

मैं ऊपर के रूप में

val pairs = weakTypeOf[T].declarations.collect { 
    case m: MethodSymbol if m.isAccessor && !m.annotations.exists(???) => 
     val name = c.literal(m.name.decoded) 
     val value = c.Expr(Select(model, m.name)) 
     reify(name.splice -> value.splice).tree 
} 

टुकड़ा को संशोधित करने के बारे में सोच रहा हूँ, लेकिन मैं नहीं मिल सकता है कि मैं क्या exists भाग में लिखने के लिए की जरूरत है। के रूप में मुझे @transient कैसे मिलेगा, इसलिए मैं इसे वहां से पारित कर सकता हूं?

अग्रिम धन्यवाद!

उत्तर

11

एनोटेशन val पर होगा, न कि एक्सेसर पर।

case m: MethodSymbol if m.isAccessor && !isTransient(m) => 

ध्यान दें कि isTransient के संस्करण मैं दे दिया है:

def isTransient(m: MethodSymbol) = m.accessed.annotations.exists(
    _.tpe =:= typeOf[scala.transient] 
) 

अब आप बस में अपने collect निम्नलिखित लिख सकते हैं: val उपयोग करने के लिए सबसे आसान तरीका है MethodSymbol पर accessed विधि के माध्यम से है यहां आपके मैक्रो में परिभाषित किया जाना चाहिए, क्योंकि इसे c.universe से आयात की आवश्यकता है, लेकिन यदि आप कई मैक्रोज़ में इस तरह की चीज कर रहे हैं तो आप Universe तर्क जोड़कर इसे कारगर बना सकते हैं।

+1

फिर से धन्यवाद! मुझे एनोटेशन प्राप्त नहीं हो रहा है। मैंने उपरोक्त उदाहरण वर्ग में 'name' और' numPosts' से पहले '@ क्षणिक 'जोड़ा, लेकिन वे अभी भी मानचित्र में जोड़े गए हैं। आश्चर्यजनक रूप से 'isTransient' के माध्यम से जाने वाली विधियों में से कोई भी कोई एनोटेशन उपलब्ध नहीं है। 'M.accessed.annotations' और' m.annotations' दोनों खाली हैं। – Emre

+1

यह बहुत अजीब है- यह मेरे लिए दोनों मामलों में अपेक्षित के रूप में काम करता है। क्या आप शायद अपना सटीक कोड पोस्ट कर सकते हैं? –

+0

यहां [कोड] है (http://pastebin.com/PmW5qg3P)। ध्यान दें कि मैं यहां कुछ अलग-अलग निर्माण कर रहा हूं - किसी दिए गए पैकेज के तहत सभी फ़ील्ड और फील्ड क्लास के फील्ड प्रकारों का नक्शा। क्या समस्या कमजोर नहीं है? अग्रिम में धन्यवाद। – Emre

संबंधित मुद्दे