Why do you want to do this with a local variable?
First, I’d like to know a little bit more about ruby. And I would
have
found such a thing useful once or twice in the past.
Secondly (the background for my question), I’d like to implement some
ocaml’ish match command (for the moment, as some kind of exercise
only).
I’m not sure yet how this could best be done but I thought it would
be
nice if it could look somewhat like this:
val = Foo(1, 2)
case val
when Foo(:x, :y)
a = x * y
when Bar(:x)
a = x
end
But this form would require the variables to be set from Foo#=== which
I
don’t think is possible anyway.
What I managed to do is this:
class Matchtype
class << self
def match(other, &block)
if other.class == self
block.call(*other.value)
true
else
false
end
end
end
attr_reader :value
def initialize(*value)
@value = value
end
end
Sample use:
class Foo < Matchtype
end
class Bar < Matchtype
end
x = Foo.new(1, 2)
y = Bar.new(1)
if Foo.match(x) {|a, b| p "Foo", a + b}
elsif Bar.match(x) {|a| p "Bar", a}
end
if Foo.match(y) {|a, b| p "Foo", a + b}
elsif Bar.match(y) {|a| p "Bar", a}
end
But this is quite useless the way it is because the value of the
block
cannot be used and because it’s ugly and …
One could of course do it this way which would come close:
class Boo < Array
end
class Baa < Array
end
z = Boo[1, 2]
case z
when Baa
p "Nope"
when Boo
a, b = z
p "Boo", a + b
end
It would be nice being able to eliminate the “a, b = z” line though.
Ideally, one would also be able to do something like this:
z = Boo[1, :a]
case z
when Boo(0, '')
p "Nope"
when Boo(1, :a)
p "Boo", a
end
Any ideas are welcome.
Regards,
Thomas.