You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby中self为类或实例时如何获取不带内存地址的正确类名

问题描述

开发了提供日志打印能力的Ruby模块,部分类通过extend引入该模块,其余类通过include引入该模块,日志打印逻辑需要传入对应类名作为参数。
初始使用如下方式调用日志方法:

global_logger.call(level, self, msg)

不同模块引入方式会输出两种不同结果:

  • 模块被extend引入时,输出格式为WARN -- Some::Class: some msg,类名展示正常
  • 模块被include引入时,输出格式为WARN -- #<Some::OtherClass:0x00007fdc04907710>: some msg,展示带内存地址的实例字符串,不符合预期

如果将传入参数改为self.class,会出现新的问题:

  • include场景下类名展示正常
  • extend场景下会输出固定内容Class,同样不符合预期

核心需求:在无法预先判断self是类本身还是类实例的前提下,获取正确的类名,避免输出带内存地址的实例对象表示字符串。

解决方案

直接通过判断self是否为类/模块类型,动态选择取值即可,代码如下:

# 统一获取日志归属的类对象
target_class = self.is_a?(Module) ? self : self.class
global_logger.call(level, target_class, msg)

实现原理

  • 当模块通过extend引入时,日志方法会作为类方法挂载到目标类上,方法执行时的self直接指向目标类本身。Ruby中所有类、模块都是Module类的子类实例,因此self.is_a?(Module)判断返回true,直接返回self即可拿到正确的类对象。
  • 当模块通过include引入时,日志方法会作为实例方法挂载到目标类上,方法执行时的self指向类的实例对象。普通业务实例不属于Module体系,判断返回false,此时取self.class即可拿到实例对应的类对象。

拿到正确的类对象后,后续无论是调用.name获取全限定类名字符串,还是做自定义格式化,都不会出现带内存地址的实例字符串问题。

内容的提问来源于stack exchange,提问作者Peter R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 08:15:35