如何使自定义Ruby类型的行为类似于字符串?
如果我有一个自定义的Ruby类,它表示某种字符串类型,如如何使自定义Ruby类型的行为类似于字符串?,ruby,Ruby,如果我有一个自定义的Ruby类,它表示某种字符串类型,如 class MyString end 为了使以下用例成为可能,我应该实现哪些功能: 每当需要MyString时传递Ruby字符串 只要需要Ruby字符串,就传递一个MyString 将Ruby字符串与MyString值进行比较(我使用s==t还是t==s应该无关紧要) 我已经看到了各种有趣的函数,如to_s、cmp、==和eq,但我不清楚它们是何时被调用的 我的具体用例是,我正在使用C API编写一个Ruby扩展,它公开了接受(并返回)
class MyString
end
为了使以下用例成为可能,我应该实现哪些功能:
MyString
时传递Ruby字符串MyString
MyString
值进行比较(我使用s==t
还是t==s
应该无关紧要)to_s
、cmp
、==
和eq
,但我不清楚它们是何时被调用的
我的具体用例是,我正在使用C API编写一个Ruby扩展,它公开了接受(并返回)自定义字符串类型(确切地说)值的函数,我的扩展也注册了该值。但是,我希望使这些自定义字符串尽可能直观。不幸的是,我不能从我的C代码返回Ruby字符串,因为应该可以对字符串调用Qt方法。至少有三种方法:
classmystring
#到_
#到_str
#to_s
是一个显式转换器,这意味着它必须出现在Ruby代码中才能工作
#to_str
是一个隐式转换器,这意味着Ruby解释器将在需要字符串但得到其他内容时尝试调用它
更新:
下面是一个你可以通过to_str
获得乐趣的例子:
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'
#尽管给String子类一个新的初始化
方法来导入这些QString类型的字符串很有诱惑力,但您可能只想添加一个有助于转换的String扩展,这样就不必重新实现String本身的版本
例如,使用两种方法,您几乎可以做到这一点:
class String
def self.from_qstring(qstring)
new(...)
end
def to_qstring
# ...
end
end
在您开始比较字符串之前,为字符串提供多种存储类型不会是一个问题,但鉴于Ruby的字符串非常健壮,编写类似的存储类型是很困难的。一般来说,将其他人在Ruby中构建的类进行子类化不是一个好主意,因为太多事情可能会出错。(例如,您可以在不知道的情况下重写内部方法。)
1) 定义Mystring.to_以获得从Mystring到字符串的自动转换
2) 不知道你这是什么意思。如果您想要一个返回Mystring的String方法,则必须使用monkey-patch-String:
Class String
def to_mystring
return Mystring.new(self)
end
end
3) 要获取t==s(假设s是String的实例,t是Mystring的实例),请定义。要获得s==t,您必须再次使用猴子补丁字符串。啊,#3对我来说是新事物-这很有趣!如果我实现了to_str
,我不会免费得到to_str
,因为to_s
是一个字符串方法吗?@Frerich,to_str
不是很神奇,它只是核心类功能的一部分,所以你可以有一个,但不能有另一个。