在Scala中有没有办法获取参数的方法名称和类?

时间:2011-05-03 11:03:39

标签: scala

在我的工作中,我们使用Hibernate,Spring和JSF的典型重型企业堆栈来处理我们的应用程序,但在学习Scala后,我想尝试在更小的Scala堆栈中复制我们的大部分功能(Squeryl, Scalatra,Scalate)看看我是否可以减少代码并提高性能(阿基里斯现在为我们治病)。

通常我的做事方式受到我们之前的堆栈的影响,所以我愿意接受一种更接近Scala范式的做法的建议。但是,我根据我们在Java代码库中的先前范例选择了我所做的一些事情,以便其他团队成员希望能够更好地接受我正在做的工作。但这是我的问题:

我们有一个像这样的域类:

class Person(var firstName: String, var lastName: String)

在玉石模板中,我拨打电话:

.section
  - view(fields)

支持类有一个如下字段列表:

class PersonBean(val person: Person) {
  val fields: Fields = Fields(person,
    List(
      Text(person.firstName),
      Text(person.lastName)
    ))
}

Fields有一个基础对象(person)和一个Field对象列表。其模板打印其所有字段模板。文本扩展了Field,它的Jade模板应该打印出来:

<label for="person:firstName">#{label}</label>: <input type="text" id="person:firstName" value="#{value}" /> 

现在#{value}只是对person.firstName的调用。但是,为了找出标签,我引用了ResourceBundle并需要生成一个字符串键。我正在考虑使用命名约定,如:

person.firstName.field=First Name

那么问题就变成了,我怎么能在Text类(或父Field类)中发现传入的参数是什么?有没有办法可以在person.firstName中传递并发现它在类Person上调用firstName?最后,我是否完全错了?

4 个答案:

答案 0 :(得分:4)

如果你想在野外散步,Scala中有一个(隐藏的)API,允许你在运行时获取代码的语法树。

这个咒语类似于:

scala.reflect.Code.lift(f).tree

这应该包含您需要的所有信息,然后是一些信息,但是您的工作将会减少解释输出。

您还可以在此处阅读有关此主题的更多信息:Can I get AST from live scala code?

虽然被警告......它被正确归类为实验性的,这样做需要您自担风险!

答案 1 :(得分:1)

你永远不能在Java中执行任何地方,所以我不完全清楚你是如何遵循你习惯的习惯用法的。这是不可能的明显原因是Java是按值传递的。所以在:

public void foo(String s) { ... }

没有任何意义,参数s不是它的东西。 person.firstName只是因为您致电foo而非:

foo(person.firstName);

因为person.firstNames 是完全独立的引用

答案 2 :(得分:0)

您可以做的是将字段(例如firstname)替换为具有name属性的实际对象。

我在最近的博客文章中做了类似的事情:http://blog.schauderhaft.de/2011/05/01/binding-scala-objects-to-swing-components/

该属性没有名称属性(但),但它是一个完整的对象,但仍然像字段一样容易使用。

答案 3 :(得分:0)

如果以下内容完全是胡说八道,我不会感到非常惊讶:

  • 使传递的A类型的参数类型不是A而是Context[A]
  • 创建一个隐式,将任何A转换为Context[A],同时这样做会在按名称调用参数中捕获参数的值
  • 然后使用反射来检查在
  • 中传递的call-by-name参数

为了实现这一目标,您需要非常具体地了解如何将内容转换为按名称调用功能;以及如何提取您想要的信息(如果它存在的话)。