递归更新动态? (Scala for the Impatient,Chapter 11,Exercise 11)

时间:2017-04-11 10:15:37

标签: scala

我目前正在使用Cay Horstmann的(优秀)Scala For the Impatient (2nd Edition)自学Scala。 第11章练习11 的任务是使用 extends Dynamic 编写一个类,它允许获取和设置系统属性,其用法如下:

val props = new DynamicProps(System.getProperties)
val javaHome = props.java.home
props.set.some.property = "somevalue"

我能够使用 selectDynamic 来获取属性(虽然我认为解决方案很笨重并需要改进):

import scala.language.dynamics

class DynamicProps(val props: java.util.Properties) extends Dynamic {
  def selectDynamic(name:String): DPropHelper = {
    new DPropHelper(name, props)
  }
}

class DPropHelper(val name: String, val props: java.util.Properties) extends Dynamic {
  def selectDynamic(name:String): DPropHelper = {
    new DPropHelper(this.name + "." + name, props)
  }
  override def toString: String = props.getProperty(name)
}

但是我完全失去了如何使用相应的 updateDynamic ,试过这个:     import scala.language.dynamics

class DynamicProps(val props: java.util.Properties) extends Dynamic {
  def updateDynamic(name: String)(value: String): DPropHelper = {
    new DPropHelper(name, props)
  }

  def update(key: String, property: String) = {
    println(s"DynamicProps update(${key}, ${property}) called")
  }

  def selectDynamic(name:String): DPropHelper = {
    new DPropHelper(name, props)
  }
}

class DPropHelper(val name: String, val props: java.util.Properties) extends Dynamic {
  def updateDynamic(name: String)(value: String): DPropHelper = {
    new DPropHelper(this.name + "." + name, props)
  }

  def selectDynamic(name:String): DPropHelper = {
    new DPropHelper(this.name + "." + name, props)
  }

  def update(key: String, property: String) = {
    println(s"DPropHelper update(${key}, ${property}) called")
  }

  override def toString: String = props.getProperty(name)
}

我非常确定我不需要帮助程序类,并且可以通过构建"堆栈"来获得相同的效果。本地列表中的路径值并返回 this ,或者只是递归地构建新的 DynamicProps

我的问题是,我怎么设法使用 updateDynamic 来最终触发更新操作 - 我的上述测试表明, update()方法都没有火。

修改 - 可能的解决方案

Rubber Duck Debugging的最佳状态中,我提出了一个可能的解决方案。现在这已经按预期工作了,虽然我会欢迎有关风格改进的建议,因为这仍然感觉非常笨重:

import scala.language.dynamics

class DynamicProps(val props: java.util.Properties) extends Dynamic {
  def updateDynamic(name: String)(value: String): DPropHelper = {
    new DPropHelper(name, props)
  }

  def selectDynamic(name:String): DPropHelper = {
    new DPropHelper(name, props)
  }
}

class DPropHelper(val name: String, val props: java.util.Properties) extends Dynamic {

  def updateDynamic(name: String)(value: String): Unit = {
    props.setProperty(this.name + "." + name, value)
  }

  def selectDynamic(name:String): DPropHelper = {
    new DPropHelper(this.name + "." + name, props)
  }

  override def toString: String = props.getProperty(name)
}

和测试

import org.scalatest.{FlatSpec, Matchers}
class DynamicPropsTest extends FlatSpec with Matchers {
  "property" should "be retrievable" in {
    val instance = new DynamicProps(System.getProperties)
    val result = instance.java.home
    result.toString should be (System.getProperties.getProperty("java.home"))
  }

  "property" should "be settable" in {
    val instance = new DynamicProps(System.getProperties)
    instance.fred.mary.jane = "alice"
    System.getProperties.getProperty("fred.mary.jane") should be ("alice")
  }
}

0 个答案:

没有答案