Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使自定义Ruby类型的行为类似于字符串?_Ruby - Fatal编程技术网

如何使自定义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扩展,它公开了接受(并返回)

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

class MyString
end
为了使以下用例成为可能,我应该实现哪些功能:

  • 每当需要
    MyString
    时传递Ruby字符串
  • 只要需要Ruby字符串,就传递一个
    MyString
  • 将Ruby字符串与
    MyString
    值进行比较(我使用
    s==t
    还是
    t==s
    应该无关紧要)
  • 我已经看到了各种有趣的函数,如
    to_s
    cmp
    ==
    eq
    ,但我不清楚它们是何时被调用的


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

    至少有三种方法:

  • classmystring
  • 定义
    #到_
  • 定义
    #到_str
  • 同时执行#2和#3将使对象的行为非常像真正的字符串,即使它不是子类

    #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
    不是很神奇,它只是核心类功能的一部分,所以你可以有一个,但不能有另一个。