我正在做练习。IO -说明很长,与这个问题无关,但你可以在这里找到我的完整解决方案。
基本上我有一个Robot
类和3个私有方法:
def rand_letters
('A'..'Z').to_a[rand(26)]
end
def rand_numbers
(0..9).to_a[rand(10)]
end
我要做的是把这些传递给另一个私有方法,像这样:
def set_name
@name = ((1..2).map(&:rand_letters) + (3..5).map(&:rand_numbers)).join
end
当我这样做时,我得到错误:undefined method 'rand_letters' for 1:Fixnum
。在看了这个问题之后,我认为问题可能是我的类没有to_proc方法。不幸的是,我不知道如何纠正这一点。我试着让我的类从Proc
继承,但我被困在如何覆盖to_proc
。如果能给我指出正确的方向,我将不胜感激。
首先:您可以使用array.sample
而不是array[rand(x)]
从数组中获取随机元素。
此外,您可以用n.times.map
替换(1..n).map
:
(2.times.map { rand_letters } + 3.times.map { rand_numbers }).join
但是使用map
对我来说是违反直觉的。如果我们能简单地取3个随机字母不是更容易吗?
这可以通过返回Enumerator
而不是单个值来实现。复数命名已经表明rand_
方法应该返回多个值:
def rand_letters
return enum_for(__method__) unless block_given?
loop { yield ('A'..'Z').to_a.sample }
end
def rand_numbers
return enum_for(__method__) unless block_given?
loop { yield (0..9).to_a.sample }
end
允许我们调用Enumerable#take
:
(rand_letters.take(2) + rand_numbers.take(3)).join
#=> "ZJ010"
或者使用[...]
文字:
[rand_letters.take(2), rand_numbers.take(3)].join
解决方案如下:
def rand_letters
('A'..'Z').to_a[rand(26)]
end
def rand_numbers
(0..9).to_a[rand(10)]
end
p ((1..2).map { rand_letters } + (1..3).map { rand_numbers }).join
当您使用map(&:rand_letters)
语法时,您向集合的每个元素发送消息。在我们的例子中,Fixnum
对象接收消息(:rand_letters),但不能响应该消息,因为它没有在类Fixnum
在我的例子中,消息:rand_letters
和:rand_numbers
没有传递给Fixnum
实例,而是传递给self
,在那里定义了它们。
如何在类中使用它:
class A
def rand_letters
('A'..'Z').to_a[rand(26)]
end
def rand_numbers
(0..9).to_a[rand(10)]
end
def name
(1..2).map { rand_letters } + (1..3).map { rand_numbers }.join
end
end
A.new.name