Ruby:Case使用对象

And*_*rew 6 ruby case object

有没有办法隐式调用case语句的对象上的方法?IE:

class Foo

  def bar
    1
  end

  def baz
    ...
  end

end
Run Code Online (Sandbox Code Playgroud)

我希望能做的就是这样......

foo = Foo.new
case foo
when .bar==1 then "something"
when .bar==2 then "something else"
when .baz==3 then "another thing"
end
Run Code Online (Sandbox Code Playgroud)

...其中"when"语句正在评估case对象上方法的返回.这样的结构有可能吗?如果是这样的话,我一直无法弄清楚语法......

hel*_*lly 9

FWIW,您根本不需要将对象传递给1.8.7中的case语句.

foo = Foo.new()
case
when foo.bar == this then that
when foo.baz == this then that
end
Run Code Online (Sandbox Code Playgroud)

我很惊讶.

http://www.skorks.com/2009/08/how-a-ruby-case-statement-works-and-what-you-can-do-with-it/


Jer*_*ten 7

什么case .. when所做的就是调用该方法===在你的when价值观,通过你的foo对象作为参数传递给===方法.所以在这段代码中:

case foo
when 1 then "something"
when 2 then "something else"
when 3 then "another thing"
end
Run Code Online (Sandbox Code Playgroud)

1 === foo然后2 === foo,它会尝试,3 === foo直到其中一个返回真值.

制作case .. when更强大的一种方法是使用Procs作为when值.我不确定早期版本的Ruby,但在1.9中,proc === x相当于proc.call(x).所以你可以写这样的代码:

case foo
when Proc.new { foo.bar == 1 } then "something"
when Proc.new { foo.bar == 2 } then "something else"
when Proc.new { foo.baz == 3 } then "another thing"
end
Run Code Online (Sandbox Code Playgroud)

请注意,我们甚至不必foo进入Procs,因为我们已经可以访问它.我不认为这是一个非常好的控制结构选择这个例子,一个简单的ifs链会更有意义:

if foo.bar == 1
  "something"
elsif foo.bar == 2
  "something else"
elsif foo.baz == 3
  "another thing"
end
Run Code Online (Sandbox Code Playgroud)


equ*_*nt8 6

对于想要测试对象的真实方法值的不同场景

class Foo
  def approved?
    false
  end

  def pending?
    true
  end
end

foo = Foo.new
case foo
when :approved?.to_proc
  puts 'Green'
when :pending?.to_proc
  puts 'Amber'
else
  puts 'Grey'
end

# This will output:  "Amber"
Run Code Online (Sandbox Code Playgroud)