Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
当配置遇到 Scala宏
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Lunfu Zhong
June 06, 2015
Programming
370
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
890
如何准备一场主题分享
zhongl
1
330
项目求生指南
zhongl
0
380
LEGO - let's build everything by scala
zhongl
1
290
Real-world Scala
zhongl
2
170
JVM运行时诊断工具 HouseMD
zhongl
0
510
Art of The Code
zhongl
1
260
Other Decks in Programming
See All in Programming
Lemonade + Foundry Toolkit でお手軽アプリ開発
seosoft
1
310
Modding RubyKaigi for Myself
yui_knk
0
900
Javaの型とAI時代に型が大事な理由 / java types and type in AI era
kishida
2
110
ADKを使って簡単にAIエージェントを作ってみよう
k1mu21
0
240
JavaDoc 再入門
nagise
0
300
CLIであることを活かしたGitHub Copilot CLI活用術 / GitHub Copilot CLI Pro Tips & Tricks
nao_mk2
1
1.2k
Claspは野良GASの夢をみるか
takter00
0
170
tsserverとは何だったのか、これからどうなるのか
nowaki28
1
460
Language Server 使ってる? 〜VSCode と Zed の場合〜 / Are you using a Language Server? ~For VS Code and Zed~
handlename
0
770
フロントエンドとバックエンドで「1文字」を揃えよう
youkidearitai
PRO
0
220
DynamoDBには集計系のクエリがないけどなんとかしたい
musan
1
130
Java × distroless で 軽量なコンテナイメージを / Java on Distroless
contour_gara
0
510
Featured
See All Featured
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
The agentic SEO stack - context over prompts
schlessera
0
800
Discover your Explorer Soul
emna__ayadi
2
1.1k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
AI: The stuff that nobody shows you
jnunemaker
PRO
8
690
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
460
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
200
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
210
Building Applications with DynamoDB
mza
96
7.1k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
770
A designer walks into a library…
pauljervisheath
211
24k
The Spectacular Lies of Maps
axbom
PRO
1
790
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]