作为我的ruby学习的一部分,我想在size
内调用rjust
方法将其作为第一个参数传递。不知道怎么做。
例如
2.to_s(2) #=> returns "10"
现在,我想在rjust
上使用10
作为第一个参数传递:size + 5
来获取*****10
2.to_s(2).rjust(how_to_get_size_of_10_and_add_5, "*") #=> dont know how to.
不成功,尝试了下面的内容:
2.to_s(2).tap{|s| rjust(s.size+5,"*")} #=> ...undefined method `rjust' for main:Object
2.to_s(2).rjust(send(:size)+5,"*") #=> ... undefined method `size' for main:Object
我试图理解如何在方法调用链的一部分上引用和运用方法。在我的示例中,我尝试在rjust
上致电2.to_s(2)
,并在rjust中引用size
的{{1}}。对不起,如果我的写作很笨拙
答案 0 :(得分:4)
我不明白为什么你间接地这样做,但也许你试图做的是:
2.to_s(2).tap{|s| break s.rjust(s.size + 5, "*")}
Ruby核心中提出了一种新方法,用于这种情况,但目前还没有。同时,您必须使用tap
和break
的组合。
答案 1 :(得分:2)
让我们把为什么的理由放在一边 。我将回答直接问题,""。
如果您的字符串是一个集合,那么它就是一个简单的map
。因此,我们可以将字符串包装在数组(一个元素)中,映射然后解包。
Array(2.to_s(2)).map{|str| str.rjust(str.size + 5, '*') }.first # => "*****10"
不幸的是,单个对象没有map
。但我们可以使用tap
+ break
hack来解决此问题。
2.to_s(2).tap{|str| break str.rjust(str.size + 5, '*')} # => "*****10"
答案 2 :(得分:2)
我认为打印五颗星和一个数字可以表达得更简单("*****%b" % 2
正如@stefan在评论中所建议的那样),但你也可以这样做:
2.to_s(2).instance_eval do
rjust(size + 5, '*')
end
但是,tap
+ break
- 黑客(由@sawa和@sergio建议)优于此解决方案。它比使用instance_eval
快2-3倍,而instance_eval
通过替换self
来绕过封装。
所以,除了学术兴趣或打高尔夫球之外,不要在你的情况下使用instance_eval
:)
基准测试结果如下:
tap+break 2.020000 0.000000 2.020000 ( 2.017987)
instance_eval 5.380000 0.000000 5.380000 ( 5.383094)
基准脚本是:
require 'benchmark'
n = 5000000
Benchmark.benchmark do |x|
x.report("tap+break") do
n.times do
'10'.tap { |str| break str.rjust(str.length + 5, '*') }
end
end
x.report("instance_eval") do
n.times do
'10'.instance_eval { rjust(length + 5, '*') }
end
end
end
答案 3 :(得分:0)
最简单的解决方案是:
'*' * 5 + 2.to_s(2)
这将始终在字符串前加上5个星号。