如何让自定义Ruby类型在行为上表现得如同字符串般灵活?

2026-04-11 18:211阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计470个文字,预计阅读时间需要2分钟。

如何让自定义Ruby类型在行为上表现得如同字符串般灵活?

若我有一个表示某种字符串类型的自定义 Ruby 类 `MyString`,就像在 `class MyString` 中,我应该实现以下功能,以便能够使用以下示例:

- 当需要 `MyString` 时,传递 Ruby 字符串- 当需要 Ruby 字符串时,传递 `MyString`

如果我有一个表示某种字符串类型的自定义 Ruby类,就像在

class MyString end

我应该实现哪些功能才能使以下用例成为可能:

>每当需要MyString时传递Ruby字符串
>每当需要Ruby字符串时传递MyString
>将Ruby字符串与MyString值进行比较(无论我使用s == t还是t == s都无关紧要).

我已经看到了各种有趣的函数,比如to_s,cmp,==和eq,但是当我们调用每个函数时我都不清楚.

我的具体用例是我正在使用C API编写一个Ruby扩展,它公开了接收(并返回)自定义字符串类型(准确地说是QString)的值的函数,我的扩展也会注册这些值.但是,我想让这些自定义字符串尽可能直观.不幸的是,我不能只从我的C代码返回Ruby字符串,因为它应该可以在字符串上调用Qt方法.

至少有三种方法:

> class MyString<串; ...;结束
>定义#to_s
>定义#to_str

同时执行#2和#3将使对象非常像真正的String,即使它不是子类.

#to_s是一个显式转换器,这意味着它必须出现在Ruby代码中才能工作.

#to_str是一个隐式转换器,这意味着Ruby解释器会在需要String时尝试调用它,但是会给出其他内容.

更新:

以下是to_str可以带来的一些乐趣的例子:

如何让自定义Ruby类型在行为上表现得如同字符串般灵活?

begin open 1, 'r' rescue TypeError => e p e end class Fixnum def to_str; to_s; end end open 1, 'r'

运行时,第一次打开失败并出现TypeError,但第二次打开则查找1.

#<TypeError: can't convert Fixnum into String> fun.rb:9:in `initialize': No such file or directory - 1 (Errno::ENOENT) from fun.rb:9:in `open'

本文共计470个文字,预计阅读时间需要2分钟。

如何让自定义Ruby类型在行为上表现得如同字符串般灵活?

若我有一个表示某种字符串类型的自定义 Ruby 类 `MyString`,就像在 `class MyString` 中,我应该实现以下功能,以便能够使用以下示例:

- 当需要 `MyString` 时,传递 Ruby 字符串- 当需要 Ruby 字符串时,传递 `MyString`

如果我有一个表示某种字符串类型的自定义 Ruby类,就像在

class MyString end

我应该实现哪些功能才能使以下用例成为可能:

>每当需要MyString时传递Ruby字符串
>每当需要Ruby字符串时传递MyString
>将Ruby字符串与MyString值进行比较(无论我使用s == t还是t == s都无关紧要).

我已经看到了各种有趣的函数,比如to_s,cmp,==和eq,但是当我们调用每个函数时我都不清楚.

我的具体用例是我正在使用C API编写一个Ruby扩展,它公开了接收(并返回)自定义字符串类型(准确地说是QString)的值的函数,我的扩展也会注册这些值.但是,我想让这些自定义字符串尽可能直观.不幸的是,我不能只从我的C代码返回Ruby字符串,因为它应该可以在字符串上调用Qt方法.

至少有三种方法:

> class MyString<串; ...;结束
>定义#to_s
>定义#to_str

同时执行#2和#3将使对象非常像真正的String,即使它不是子类.

#to_s是一个显式转换器,这意味着它必须出现在Ruby代码中才能工作.

#to_str是一个隐式转换器,这意味着Ruby解释器会在需要String时尝试调用它,但是会给出其他内容.

更新:

以下是to_str可以带来的一些乐趣的例子:

如何让自定义Ruby类型在行为上表现得如同字符串般灵活?

begin open 1, 'r' rescue TypeError => e p e end class Fixnum def to_str; to_s; end end open 1, 'r'

运行时,第一次打开失败并出现TypeError,但第二次打开则查找1.

#<TypeError: can't convert Fixnum into String> fun.rb:9:in `initialize': No such file or directory - 1 (Errno::ENOENT) from fun.rb:9:in `open'