获取对象中调用者类的名称的最佳方法是什么?

2024-03-26

我可以使用这个来完成这个工作:

scala> object LOGGER {
     | def warning(msg: String)(implicit className:String) = {
     |   className
     | }
     | }
defined object LOGGER

scala> class testing {
     | lazy implicit val className = this.getClass.getName
     | def test = LOGGER.warning("Testing")
     | }
defined class testing

scala> val obj = new testing()
obj: testing = testing@11fb4f69

scala> obj.test
res51: String = testing <=======

scala> class testing2 {
     | lazy implicit val className = this.getClass.getName
     | def test = LOGGER.warning("Testing")
     | }
defined class testing2

scala> val obj2 = new testing2()
obj2: testing2 = testing2@2ca3a203


scala> obj2.test
res53: String = testing2 <=====

我还尝试在中使用 Thread.currentThread.getStackTraceobject LOGGER但无法让它打印调用类testing in the warning功能。 还有其他方法可以做到这一点吗?


动态变量

一种方法是动态变量 http://www.scala-lang.org/api/current/index.html#scala.util.DynamicVariable

import scala.util.DynamicVariable
object LOGGER {
  val caller = new DynamicVariable[String]("---")
  def time = new Date().toString
  def warning(msg: String) = println(s"[${caller.value} : $time] $msg")
}

trait Logging {
  def logged[T](action: => T) = LOGGER.caller.withValue(this.getClass.getName)(action)
}

class testing extends Logging {
  def test = logged {
    //some actions
    LOGGER.warning("test something")
    //some other actions
  }
}

val t = new testing

t.test

会打印类似的东西

[测试:11 月 25 日星期三 11:29:23 MSK 2015] 测试一些东西

或者代替混合Logging你可以直接使用它

class testing {
  def test = LOGGER.caller.withValue(this.getClass.getName) {
    //some actions
    LOGGER.warning("test something")
    //some other actions
  }
}

Macro

另一种更强大但更复杂的支持方法是构建一些简单的macro http://docs.scala-lang.org/overviews/quasiquotes/intro.html

您可以在其他源中定义,最好在其他子项目中定义

import scala.reflect.macros.blackbox.Context
import scala.language.experimental.macros
class LoggerImpl(val c: Context) {
  import c.universe._

  def getClassSymbol(s: Symbol): Symbol = if (s.isClass) s else getClassSymbol(s.owner)

  def logImpl(msg: Expr[String]): Expr[Unit] = {
    val cl = getClassSymbol(c.internal.enclosingOwner).toString
    val time = c.Expr[String](q"new java.util.Date().toString")
    val logline = c.Expr[String](q""" "[" + $cl + " : " + $time + "]" + $msg """)
    c.Expr[Unit](q"println($logline)")
  }
}

object Logger {
  def warning(msg: String): Unit = macro LoggerImpl.logImpl
}

现在您不需要更改测试类:

class testing {
  def test = {
    //some actions
    Logger.warning("something happen")
    //some other actions
  }
}

并查看所需的输出。

这将是运行时堆栈自省的高性能替代方案

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

获取对象中调用者类的名称的最佳方法是什么? 的相关文章

随机推荐

  • Java 线程 Random.nextLong() 返回相同的数字

    我正在使用一个 OAuth 库 它调用 new Random nextLong 来生成随机数 但它在异步调用上生成相同的随机数 我已将其范围缩小到线程 Random nextLong 以便经常返回相同的确切数字 有谁知道这是否是 Java
  • 将 OpenPGP 签名添加到已签名的文档中? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我们想要实现一个需要多人对文档进行数字签名的工作流程 如果我自己的钥匙串中有多个秘密密钥 我可以做一些简单的事情 gpg sign u userid1
  • 函数不接受 1 个参数 C++

    我的代码有问题 因为我无法弄清楚为什么会收到错误 这是代码 using namespace std void presentValue bool stringChar bool stringVal double futureValConv
  • 如何在 Makefile.am 中指定我想要 C++0x?

    目前我的项目有以下简单的树 Makefile am configure ac README src main cpp src Makefile am bin 我正在尝试遵循以下教程 http www gnu org software aut
  • window.onload = init(); 和有什么区别和 window.onload = init;

    根据我收集的信息 前者将函数返回语句的实际值分配给 onload 属性 而后者分配实际函数 并将在窗口加载后运行 但我还是不确定 感谢任何可以详细说明的人 window onload init 将 onload 事件分配给任何returne
  • 如何在sparkR中创建一个新的DataFrame

    在sparkR中我有data作为数据框 我可以附加一个条目data像这样 newdata lt filter data data column 1 我怎样才能附加多个 假设我想附加向量中的所有元素list lt c 1 6 10 11 14
  • 唯一的表单令牌禁用用户的多任务处理

    如果我想保护我的网站和用户免受跨站伪造 CSRF 攻击 我可以生成一个唯一的令牌 token md5 time rand on 每一页有一个形式 令牌在隐藏的输入字段中提交echo
  • 在Excel 2007中,为什么拖动手动水平分页会导致之前的自动分页变为手动分页?

    在过去的几天里 我一直在编写一些 Excel 2007 VBA 代码 用于管理复杂工作表中的分页符 经过多次挫折后 我刚刚解决了一个让我发疯的 跳页符 问题 并且我做出了以下发现 这让我想到了一个问题 为什么 在分页视图中 使用鼠标拖动ma
  • 如何使用 C# 执行 powershell 脚本并设置执行策略?

    我尝试结合 stackoverflow 中的两个答案 first https stackoverflow com questions 527513 execute powershell script from c sharp with co
  • HMLocation 事件示例

    我正在我的 HMHome 中实现 HMLotinEvent 我正在尝试下面的代码 但我没有得到的一件事是我不知道如何执行功能 例如如果我离开家必须关闭所有灯 我没有找到任何与操作集相关的方法 如果我错了 请纠正我 要求 我想关闭所有配件 以
  • iPad3 高分辨率视网膜显示问题

    我正在使用 Xcode 4 2 iOS SDK 5 0 为 iPad3 Retina Display 开发一个应用程序 我正在使用以下代码片段来检测视网膜 高分辨率 显示 if UIScreen mainScreen respondsToS
  • 没有函数体的函数是什么意思?

    我正在阅读打包的代码time 然后我想知道如何func After d Duration lt chan Time作品 我发现代码如下 func After d Duration lt chan Time return NewTimer d
  • SASS 如何帮助我开发响应式网页设计?

    我使用 CSS 进行设计已有多年 但我现在才刚刚学习如何使用 SASS 这是一个非常初学者的问题 所以请耐心等待 我开始研究 SASS 的原因是因为我想开发响应式网页设计 但希望有一种更好的方法来实现它 而不是为每个屏幕尺寸手动制作不同的样
  • 如何使用 Python 匹配相似的坐标?

    背景 我收到了四个数据目录 其中第一个目录 我们称之为 Cat1 给出了场 1 和 2 中无线电源的坐标 赤经和赤纬 RA 和 Dec 第二个目录 Cat2 给出了 RA和 Dec 适用于领域 1 中的无线电源和红外 IR 源 第三个目录
  • RewriteBase 的值可用作变量/引用吗?

    我正在编写一个 htaccess 文件 该文件将检查请求的页面是否存在于缓存中 为了执行检查 并节省输入 我使用缓存的位置设置一个 ENV 变量 all this works as I expect
  • C函数语法,参数类型在参数列表之后声明

    我对 C 比较陌生 我遇到了一种以前从未见过的函数语法形式 其中参数类型是在参数列表之后定义的 有人可以向我解释一下它与典型的 C 函数语法有何不同吗 例子 int main argc argv int argc char argv ret
  • 长 vs {0L}[0]

    在我们的一项旧服务中 我发现了这样一段代码 评论为原创 long tasksCounter 0 boxing for long counters long errorsCounter 0 boxing for long counters 此
  • R:传递函数参数以覆盖内部函数的默认值

    在 R 中 我想做这样的事情 我有一个函数 f1 它有一个带有默认值的参数 k 3 f1 function x k 3 u x 2 k u 然后我定义了第二个函数 f2 来调用 f1 f2 function z s s f1 z 允许 f2
  • jQuery ajax() 预加载多个内容

    我使用以下代码来预加载 mp3 ajax url boom mp3 success function done 我是否可以预加载多个元素 例如图像和 mp3 e g ajax url boom mp3 moo jpg success fun
  • 获取对象中调用者类的名称的最佳方法是什么?

    我可以使用这个来完成这个工作 scala gt object LOGGER def warning msg String implicit className String className defined object LOGGER s