Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
当配置遇到 Scala宏
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Lunfu Zhong
June 06, 2015
Programming
380
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
当配置遇到 Scala宏
一个 Internal DSL 的应用案例
Lunfu Zhong
June 06, 2015
More Decks by Lunfu Zhong
See All by Lunfu Zhong
spring-boot 在统一架构体系中的价值
zhongl
2
900
如何准备一场主题分享
zhongl
1
340
项目求生指南
zhongl
0
400
LEGO - let's build everything by scala
zhongl
1
300
Real-world Scala
zhongl
2
180
JVM运行时诊断工具 HouseMD
zhongl
0
510
Art of The Code
zhongl
1
270
Other Decks in Programming
See All in Programming
iOSDC2026登壇資料.pdf
riofujimon
0
160
標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision
convto
5
7.1k
市販E-Readerを乗っ取れ 〜Embedded Swiftで電子ペーパーガジェットを制御する〜
trickart
0
190
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
140
WebMCP Challenge に星空観察アプリで参加した話
okajun35
0
170
DroidKaigi 2026 「個人開発という実験場: Android エンジニアが手にする4つの自由」
slashnephy
0
230
{ Android | Kotlin } Gradle Plugin in 2026
ryunen344
1
320
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
6
1.9k
新人はどこまで自力でやり、どこからAIに頼るべきか/エンジニア育成に向き合う_先輩たちの悩みと知見共有会
toppan_digital_dev
1
620
新卒PdEのリアル
ryu1013
1
500
Jetpack Compose メカニズム
skydoves
0
420
『寄り添うラジオ』をAIで作る 体験価値から逆算した、会話しないUXと品質設計
theoriatec2024
3
180
Featured
See All Featured
The Curse of the Amulet
leimatthew05
3
14k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
My Coaching Mixtape
mlcsv
0
310
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Believing is Seeing
oripsolob
1
220
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
330
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
450
Git: the NoSQL Database
bkeepers
PRO
432
67k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
520
The agentic SEO stack - context over prompts
schlessera
0
940
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.7k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.7k
Transcript
当配置遇到Scala宏 ⼜又⼀一个 Internal DSL 的应⽤用案例
关于我 Scala, Java, Big Data, Message Middleware
这些年我们⽤用过的配置 都有哪些?
.properties .yaml .conf .xml
相较⽽而⾔言...
醉⼈人的命名⻓长度 1 // application.properties 2 db1.jdbc.url = jdbc:mysql:10.0.0.1/demo 3 db1.jdbc.driver
= com.mysql.jdbc.Driver 4 db1.jdbc.username = jushi 5 db1.jdbc.password = ********
啰嗦的对称包围 1 <!-- logback.xml --> 2 <configuration scanscan="true" scanPeriod="3 seconds"
> 3 4 <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 5 <encoder> 6 <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> 7 </encoder> 8 </appender> 9 10 <root level="INFO"> 11 <appender-ref ref="STDOUT" /> 12 </root> 13 </configuration>
优雅地近乎完美 1 #.travis.yml 2 language: scala 3 scala: 4 -
2.11.5 5 jdk: 6 - openjdk7 7 script: 8 - sbt ++$TRAVIS_SCALA_VERSION test 9 notifications: 10 email: 11 -
[email protected]
强⼤大到没有朋友 1 // kafka.conf 2 kafka { 3 server {
4 host = localhost 5 port = 9092 6 } 7 socket { 8 timeout = 5s 9 buffer = 64K 10 } 11 client = id 12 debug = false 13 delays = 2s 14 }
None
只是...
我 讨厌 G.E.T 1 // Consumer.scala 2 class Consumer extends
Actor { 3 @inline def conf = context.system.settings.config 4 5 val client = new SimpleConsumer( 6 conf.getString("kafka.server.host"), 7 conf.getInt("kafka.server.port"), 8 conf.getDuration("kafka.socket.timeout", SECOND), 9 conf.getLong("kafka.socket.buffer"), 10 conf.getString("kafka.client") 11 ) 12 13 ... 14 }
None
然后,我想到了宏
Method or Annotation
Method 1 def conf(key: String) = macro impl 2 3
def impl(c: Context)(key: c.Expr[String]) : c.Expr[Unit] = { 4 // TODO 5 } 6 7 8 val host = conf("kafka.server.host") 9 10 val host = conf.getString("kafka.server.host")
Method
Annotation 1 class conf extends StaticAnnotation { 2 def macroTransform(annottees:
Any*): Any = macro impl 3 4 private def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { 5 import c.universe._ 6 7 annottees.map(_.tree) match { 8 case ClassDef(...) :: Nil => 9 // TODO 10 11 case _ => 12 c.abort(c.enclosingPosition, "Invalid annottee") 13 } 14 } 15 }
Annotation 1 @conf trait kafka { 2 val server =
new { 3 val host: String 4 } 5 } 6 7 trait kafka { 8 val server = new { 9 val host: String = conf.getString("kafka.server.host") 10 } 11 }
如果仅仅只是映射装载 就太 TYTSSN 了
由代码⽣生成配置 1 @conf trait kafka { 2 val server =
new { 3 val host = "wacai.com" 4 val port = 12306 5 } 6 7 val socket = new { 8 val timeout = 3 seconds 9 val buffer = 1024 * 64L 10 } 11 12 val client = "wacai" 13 } 1 kafka { 2 server { 3 host = wacai.com 4 port = 12306 5 } 6 7 socket { 8 timeout = 3s 9 buffer = 64K 10 } 11 12 client = wacai 13 }
之前提到的⼜又⼀一案例 1 import lego.dsl._ 2 3 new Server { 4
5 def name = "ping-pong" 6 7 tcp.bind(port = 12306) { 8 Codec() <=> Handle { 9 case Request(_, hs, _) => Response(200, hs) 10 } 11 } 12 }
参阅 github.com/wacai/config-annotation 使⽤用 Scala Macro Annotation 实现配置项绑定 ⾸首篇 续篇 终篇
What are macros good for ?
scala macro annotations real world example
[email protected]