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
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
910
如何准备一场主题分享
zhongl
1
360
项目求生指南
zhongl
0
400
LEGO - let's build everything by scala
zhongl
1
310
Real-world Scala
zhongl
2
180
JVM运行时诊断工具 HouseMD
zhongl
0
520
Art of The Code
zhongl
1
270
Other Decks in Programming
See All in Programming
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
580
自サークルのIdPからログアウトできるようになるまで
taiseiue
0
110
wkhtmltopdfの次どうするか問題2026
willnet
2
1.9k
コードレビューのボトルネックを"する側"と"される側"の両面から解消する
yub0n
2
1.5k
The Rails Doctrine Decade
koic
2
510
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
550
KiroのSpecで「五目並べ」を作ってみる
satoshi256kbyte
1
350
RAG の “R” を Swift で覗いてみる 〜「意味から探す」検索の仕組み〜
nao_randd
0
120
外から家のPCの電源入れたい!をPHPで解決する
kawashimo0
1
110
UPDATE をやめる — EF Core でマスタをバージョン管理する
panda728
PRO
0
1.1k
技術的負債を組織課題として解く-増えすぎたマイクロサービスとの戦い-
reimaru
1
2.9k
[ハンズオン]AIへの指示だけで「五目並べ」を作ってみよう
satoshi256kbyte
1
350
Featured
See All Featured
Practical Orchestrator
shlominoach
192
12k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
203
76k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
WENDY [Excerpt]
tessaabrams
14
40k
Code Reviewing Like a Champion
maltzj
528
40k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
510
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
2
2.9k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
1k
Automating Front-end Workflow
addyosmani
1369
210k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
580
Agile that works and the tools we love
rasmusluckow
331
22k
KATA
mclloyd
PRO
35
16k
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]