ruby - rand(Range) - 没有将 Range 隐式转换为 Integer

标签 ruby

对问题的跟进 How to create a random time between a range .

Kernel#rand 适用于 Time 范围:

require 'time'
rand(Time.parse('9 am')..Time.parse('11:30 am'))

但是当我尝试使用自定义类时,我遇到了错误:

`rand': no implicit conversion of Range into Integer (TypeError)

class Int
  include Comparable

  attr_reader :num

  def initialize(num)
    @num = num
  end

  def succ
    Int.new(num + 1)
  end

  def <=>(other)
    num <=> other.num
  end

  def to_s
    "Int(#{num})"
  end

  def to_int
    @num
  end

  alias_method :inspect, :to_s
end

puts rand(Int.new(1)..Int.new(3))

为什么?我在自定义类(class)中缺少什么?我们可以在 rand(Range) 中使用这样一个自定义类吗?

最佳答案

我不知道关于 Kernel#randRange 参数的具体期望的任何文档,但我们可以通过覆盖 来了解发生了什么>respond_to? 在你的类里面,然后看着事情分崩离析:

def respond_to?(m)
  puts "They want us to support #{m}"
  super
end

这样做告诉我们 rand 想要在您的 Int 上调用 #-#+ 方法实例。考虑到 rand(a..b) 是为处理整数而设计的,这确实有一定道理。

因此我们引入了加法和减法的快速'n'dirty 实现:

def -(other)
  self.class.new(to_int - other.to_int)
end

def +(other)
  self.class.new(to_int + other.to_int)
end

我们开始从对 rand 的调用中获取 rand Int


我不确定在何处(或是否)对此进行了记录,因此请原谅您挥手致意。我通常会花一些时间研究 Ruby 源代码来回答这类问题,但我现在没有时间。

关于ruby - rand(Range) - 没有将 Range 隐式转换为 Integer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48292982/

相关文章:

ruby - 功能中的 Cucumber HTML 标记

mysql - wamp 或 xampp : how to upgrade to mysql 6?

ruby - 'T' 被添加到我的日期时间 Ruby & Resque

ruby-on-rails - 无法弄清楚是什么导致我的 Rails 应用程序出现性能瓶颈

ruby-on-rails - ruby /Redis gem : change default connection parameters

ruby-on-rails - Rails 3 中的 fields_for 问题

ruby - 如何计算带有偏移量的异或?

ruby-on-rails - 索引 View 的范围使用

ruby-on-rails - 如何检查数组中的每个单词是否包含子字符串并拒绝 Ruby on Rails 中的子字符串?

ruby-on-rails - postgres 中的 Ruby/Rails 字符串大小写比较问题