新手问题 block call 如何传参的问题

luffycn · 2014年12月05日 · 最后由 luffycn 回复于 2014年12月05日 · 2930 次阅读
href  'h2 a' do |h|
   h.first['href'].strip
end

像这样一个方法 href 带两个参数,第一个参数是字符串,第二个参数 block 有带一个参数变量 h

现在我在另外一个方法里获取了一个 block,还有相应的 h 参数值,要如何把这两个值传给 href 这个方法了?

我的例子可能不太好,你在本地运行一下,看看结果应该对你有启发。

def get_parameters
  proc = Proc.new { |text| "<a href='#{text}'>#{text}</a>" }
  ["Eric", proc] 
end

def href(text)
  puts yield(text)
end

# 方法1
href("Eric") { |text| "<a href='#{text}'>#{text}</a>" }

# 方法2
href(get_parameters[0], &get_parameters[1])

千万别照搬!!!只是一个例子,是不好的模式。

你用的 gem 吗?叫啥?

@flowerwrong 我没在用 gem, 我是在写 gem href 是 method missing 方法,在 method_missing 中,我已经根据 href 的第一个参数计算出结果,要把这个结果传到 href 的第二个参数 block 中去,不知道怎么传,block.call(t) 没办法这么用

#3 楼 @luffycn 不知道这个可以不?

def f4(n, p)
  puts n * p.call
end

f4(2, proc {4})
f4(2, lambda {4})
f4(2, Proc.new {4})
def f4(n, p)
  x = 5
  puts n * p.call(x)
end

f4(2, lambda {|x| 4+x;})

h 不是 href 的参数啊,当然不能将 h 的值传给 href 了! 在 href 函数的定义中,会计算出一个值,假设存在变量 h 中,然后将 h 传递给 block (通过 yield(h) 的方式). 所以,这个问题有错。

没看评论,误解题意了,对 method_missing 不熟,请忽略哈

#3 楼 @luffycn block.call 可以工作

class A
  def method_missing(method_name, *args, &block)
    if method_name == :href
      h = args[0].length
      block.call(h)
    else
      super
    end
  end
end

a = A.new
a.href 'h2 a' do |h|
  puts h
end

输出 4,正常

@luffycn h 这个参数肯定能传的

class Foo

  def method_missing name, *args, &block
    puts name    
    puts args.inspect 
    puts block.parameters.inspect 
  end

end

Foo.new.href 'h2 a' do |h|
  h.first['href'].strip
end

href ["h2 a"] [[:opt, :h]]

我觉得你现在的问题是什么时候给 :h 这个参数赋值,因为你现在的 href 其实是一个不存在的方法,所以你只能在 method_missing 里给 :h 一个实在的值

call 直接调用确实 是没问题,是我在其它数据上出了问题,以为是 call 参数的问题

需要 登录 后方可回复, 如果你还没有账号请 注册新账号