假设我有以下数组:
arr = [[5, 1], [2, 7]]
Run Code Online (Sandbox Code Playgroud)
我想找到最小元素,比较元素的第二个元素.最小元素将是[5, 1]因为1小于7.我可以使用以下代码:
arr.min {|a,b| a[1] <=> b[1]}
Run Code Online (Sandbox Code Playgroud)
为了计算最大值,我也可以这样做:
arr.max {|a,b| a[1] <=> b[1]}
Run Code Online (Sandbox Code Playgroud)
这给了[2, 7].
我一直使用相同的块.我想在某处拥有该块并将其提供给min/max函数.我希望这样的事情:
blo = lambda {|a,b| a[1] <=> b[1]}
arr.min blo
Run Code Online (Sandbox Code Playgroud)
会工作,但它没有.有关如何做到这一点的任何想法?
p = Proc.new{ puts 'ok' }
Run Code Online (Sandbox Code Playgroud)
有可能在proc中看到ruby代码吗?
inspect 返回内存位置:
puts p.inspect
#<Proc:0x007f9e42980b88@(irb):2>
Run Code Online (Sandbox Code Playgroud)
Ruby 1.9.3
我在理解return块,触发器和lambda中的工作方式时遇到了很多麻烦.
例如,在下面的例子中,为什么batman_ironman_proc工作,而batman_yield抛出错误?
def batman_ironman_proc
victor = Proc.new { return "Batman will win!" }
victor.call
"Iron Man will win!"
end
def batman_yield
yield
"Iron man will win!"
end
victor = Proc.new { return "Batman will win!" }
puts batman_ironman_proc
#batman_yield(&victor) === This code throws an error.
Run Code Online (Sandbox Code Playgroud) Enumerable#detect返回块计算结果的数组的第一个值true.它有一个可选的参数,需要响应call并在这种情况下被调用,返回它的值.所以,
(1..10).detect(lambda{ "none" }){|i| i == 11} #=> "none"
Run Code Online (Sandbox Code Playgroud)
为什么我们需要lambda?为什么我们不直接传递默认值,因为(在我的测试中)lambda无论如何都不能有任何参数?像这样:
(1..10).detect("none"){|i| i == 11} #=> "none"
Run Code Online (Sandbox Code Playgroud) 由于 proc 是一个对象,我可以在它自己的实例范围内创建一个 proc 吗?
例如:
prc = Proc.new do
foo
end
def prc.foo
123
end
prc.call
# NameError: undefined local variable or method `foo' for main:Object
Run Code Online (Sandbox Code Playgroud)
通过更改self或明确receiver引用 proc。
该接收器必须动态评估,例如以下应该工作:
other_prc = prc.clone
def other_prc.foo
456
end
other_prc.call
#=> 456 <- not 123
Run Code Online (Sandbox Code Playgroud)
这意味着我不能通过以下方式对其进行“硬编码”:
prc = Proc.new do
prc.foo
end
Run Code Online (Sandbox Code Playgroud)
换句话说:有没有办法从 proc 内部引用 procs 实例?
另一个没有的例子foo:(放什么# ???)
prc = Proc.new do
# ???
end
prc == prc.call #=> true
other_prc = prc.clone …Run Code Online (Sandbox Code Playgroud) 我知道Ruby中的方法不是对象,而是procs和lambdas.除此之外,他们之间有什么区别吗?因为我们都可以传球.是什么让proc对象与方法不同?
方法:
1.8.7-p334 :017 > def a_method(a,b)
1.8.7-p334 :018?> puts "a method with args: #{a}, #{b}"
1.8.7-p334 :019?> end
1.8.7-p334 :021 > meth_ref = Object.method("a_method")
=> #<Method: Class(Object)#a_method>
1.8.7-p334 :022 > meth_ref.call(2,3)
Run Code Online (Sandbox Code Playgroud)
Proc对象:
a = lambda {|a, b| puts "#{a}, #{b}"}
a.call(2,3)
Run Code Online (Sandbox Code Playgroud) 问题的灵感来自于这个问题.
Proc::new 有一个选项可以在方法中没有块调用:
Proc::new可以仅在具有附加块的方法内调用没有块,在这种情况下,该块被转换为Proc对象.
当proc/ lambdainstance作为代码块传递时,Proc正在创建新实例:
Proc.singleton_class.prepend(Module.new do
def new(*args, &cb)
puts "PROC #{[block_given?, cb, *args].inspect}"
super
end
end)
Proc.prepend(Module.new do
def initialize(*args, &cb)
puts "INIT #{[block_given?, cb, *args].inspect}"
super
end
def call(*args, &cb)
puts "CALL #{[block_given?, cb, *args].inspect}"
super
end
end)
? = ->(*args) { }
[1].each &?
#? [1]
Run Code Online (Sandbox Code Playgroud)
正如人们可能会看到,无论是呼叫Proc::new发生的事情,也没有Proc#initialize和/或Proc#call进行调用.
问题是:ruby如何创建并执行引擎盖下的块包装器?
注意:不要在pry/ irbconsole中测试上面的代码:他们知道有纯粹的执行故障,主要是因为他们修补了procs.
我期待代码
foo=proc{puts "foo"}
instance_exec(1,2,3,&foo) do |*args , &block|
puts *args
block.call
puts "bar"
end
Run Code Online (Sandbox Code Playgroud)
输出
1 2 3 foo bar
但得到了错误
both block arg and actual block given
我可以将一个本身期望块的块传递给ruby中的instance_exec吗?
有没有办法在Linux中创建链接到特定iNode的文件?采取这种情况:有一个文件正在写入(可能是一个日志),并删除了特定文件,但 dir/proc中的链接仍然指向它.在这种情况下,我们不需要它的裸副本,而是它的硬链接,因此我们可以在进程关闭之前进行未来的修改和最后修改,系统将其删除.
如果我们有iNode号码有没有办法实现这个目标?
Procs和lambdas 在方法范围和关键字的影响方面有所不同return.我对它们之间的性能差异很感兴趣.我写了一个测试,如下所示:
def time(&block)
start = Time.now
block.call
p "that took #{Time.now - start}"
end
def test(proc)
time{(0..10000000).each{|n| proc.call(n)}}
end
def test_block(&block)
time{(0..10000000).each{|n| block.call(n)}}
end
def method_test
time{(1..10000000).each{|n| my_method(n)}}
end
proc1 = Proc.new{|x| x*x}
proc2 = proc{|x| x*x}
lam1 = lambda{|x| x*x}
lam2 = ->x{x*x}
def my_method(x)
x*x
end
test(proc1)
test(proc2)
test(lam1)
test(lam2)
test_block{|x| x*x}
test(method(:my_method))
method_test
Run Code Online (Sandbox Code Playgroud)
此代码的结果如下所示.
"that took 0.988388739"
"that took 0.963193172"
"that took 0.943111226"
"that took 0.950506263"
"that took 0.960760843"
"that took 1.090146951"
"that …Run Code Online (Sandbox Code Playgroud) proc ×10
ruby ×9
lambda ×5
block ×3
closures ×1
codeblocks ×1
detect ×1
enumerable ×1
inode ×1
linux ×1
ln ×1
methods ×1
performance ×1
return ×1