标签: proc

将方法的proc作为块提供

假设我有以下数组:

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)

会工作,但它没有.有关如何做到这一点的任何想法?

ruby codeblocks proc

11
推荐指数
2
解决办法
4793
查看次数

是否有可能在proc中看到ruby代码?

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

ruby block proc

11
推荐指数
3
解决办法
5911
查看次数

在procs,lambdas和blocks中返回语句

我在理解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)

ruby lambda return block proc

11
推荐指数
1
解决办法
9972
查看次数

为什么Enumerable#detect需要一个Proc/lambda?

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)

ruby lambda enumerable detect proc

11
推荐指数
1
解决办法
1488
查看次数

我可以在其自身的上下文中创建一个 proc 吗?

由于 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 closures proc

10
推荐指数
2
解决办法
387
查看次数

方法和proc对象有什么区别?

我知道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)

ruby methods lambda proc

9
推荐指数
1
解决办法
2350
查看次数

如何在传递给`instance_exec`时执行proc

问题的灵感来自于这个问题.

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.

ruby lambda metaprogramming proc

9
推荐指数
1
解决办法
323
查看次数

我可以将一个本身期望块​​的块传递给ruby中的instance_exec吗?

我期待代码

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吗?

ruby block proc

8
推荐指数
1
解决办法
901
查看次数

Linux文件删除恢复

有没有办法在Linux中创建链接到特定iNode的文件?采取这种情况:有一个文件正在写入(可能是一个日志),并删除了特定文件, dir/proc中的链接仍然指向它.在这种情况下,我们不需要它的裸副本,而是它的硬链接,因此我们可以在进程关闭之前进行未来的修改和最后修改,系统将其删除.

如果我们有iNode号码有没有办法实现这个目标?

linux inode ln data-recovery proc

8
推荐指数
2
解决办法
7735
查看次数

proc,Proc.new,lambda和stabby lambda之间的速度差异

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)

ruby performance lambda proc

8
推荐指数
1
解决办法
2921
查看次数