Dynamic Extractors in Scala -
one of things don't extractors cannot have parameters. cannot have extractors param
in:
req match { case param("foo")(foo) => … }
dynamic extractors?
that's unfortunate, , hope change day, morning figured fix using dynamic trait.
object params extends dynamic { def selectdynamic(name: string) = new { def unapply(params: map[string, string]): option[string] = params.get(name) } }
… hoping allow me use params in pattern matching statement this:
req match { case params.foo(value) => // matching map("foo" -> "bar"), extracting "bar" in value
it doesn't work
… doesn't work. seems compiler still getting confused.
scala> map("foo" -> "bar") match { case params.foo(value) => value } <console>:10: error: value applydynamic not member of object params error after rewriting params.<applydynamic: error>("foo") possible cause: maybe wrong dynamic method signature? map("foo" -> "bar") match { case params.foo(value) => value } ^ <console>:10: error: not found: value value map("foo" -> "bar") match { case params.foo(value) => value } ^
which find surprising, since
object params { object foo { def unapply{params: map[string, string]): option[string] = … } }
would work fine. also, if assign params.foo
variable first, okay:
scala> val foo = params.foo foo: anyref{def unapply(params: map[string,string]): option[string]} = params$$anon$1@f2106d8 scala> map("foo" -> "bar") match { case foo(value) => value } warning: there 1 feature warning(s); re-run -feature details res2: string = bar
should considered bug?
the canonical answer can extractors customized parameters in body of case statement (or anywhere else extractor used)?
but the hacking blog suggests trick of passing arguments arbitrary names dynamic selection, tried in question.
$ scala welcome scala 2.11.8 (java hotspot(tm) 64-bit server vm, java 1.8.0_60). type in expressions evaluation. or try :help. scala> class x(pattern: string) { val regexp = new { def unapplyseq(s: string) = pattern.r.unapplyseq(s) } } defined class x scala> import language._ import language._ scala> case object p extends dynamic { def selectdynamic(pattern: string) = new x(pattern) } defined object p scala> "abcdef" match { case p.`.*(b.*d).*`.regexp(s) => s } res0: string = bcd
the selection required because of a crashing bug in 2.11 different 2.10 error shown in question:
scala> class regexp(pattern: string) { def unapplyseq(s: string) = pattern.r.unapplyseq(s) } defined class regexp scala> case object p extends dynamic { def selectdynamic(pattern: string) = new regexp(pattern) } defined object p scala> "abcdef" match { case p.`.*(b.*d).*`(s) => s } java.lang.nullpointerexception @ scala.tools.nsc.typechecker.patterntypers$patterntyper$class.inplaceadhocoverloadingresolution(patterntypers.scala:68)
the working example in 2.10:
$ scala210 -language:_ welcome scala version 2.10.5 (openjdk 64-bit server vm, java 1.7.0_95). type in expressions have them evaluated. type :help more information. scala> :pa // entering paste mode (ctrl-d finish) class x(key: string) { val = new { def unapply(params: map[string, string]): option[string] = params.get(key) }} object params extends dynamic { def selectdynamic(name: string) = new x(name) } // exiting paste mode, interpreting. defined class x defined module params scala> map("foo" -> "bar") match { case params.foo.get(value) => value } res0: string = bar
this similar shown @ end of question, makes obvious dynamic selection can used way.
Comments
Post a Comment