Bill Bisco - 28 days ago 8

Ruby Question

I'm trying to use the .match to recognize a single / (forward slash) character.

The line in question that is currently not working is:

`elsif i.match([/[/]/]) then`

Any help would be appreciated. I have tried mixing in \ (backward slash) but to no avail so far.

`def calc(input)`

stack = []

array1 = input.split(//) #// splits into individual characters

array1.each do |i|

if i.match(/[0-9]/) then

stack.push(i.to_i)

puts "\n" ; print stack

#array1.slice!(i.to_i)

#array1.shift

#array1.delete_at(i.to_i)

#array1.delete(i)

elsif i.match(/[+]/) then

result = stack[-2] + stack[-1]

stack.pop

stack.pop

stack.push(result)

puts "\n" ; print stack

#puts "\n" ; print array1

elsif i.match(/[-]/) then

result = stack[-2] - stack[-1]

stack.pop

stack.pop

stack.push(result)

puts "\n" ; print stack

elsif i.match(/[*]/) then

result = stack[-2] * stack[-1]

stack.pop

stack.pop

stack.push(result)

puts "\n" ; print stack

elsif i.match([/[/]/]) then

result = stack[-2].to_f / stack[-1].to_f

stack.pop

stack.pop

stack.push(result)

puts "\n" ; print stack

end

end

end

Answer Source

Since you're breaking out your input into individual characters it's not necessary to use a regular expression to compare things. You can do straight-up comparisons like `x == '/'`

. Given how many comparisons you're doing here, and they're all of a similar form, the structure you're actually looking for is to use a `case`

statement:

```
def calc(input)
stack = [ ]
# Process individual characters in the string using `chars`
input.chars.each do |c|
case (c)
when /[0-9]/
stack << c.to_i
when '+'
a, b = stack.pop(2)
stack << a + b
when '-'
a, b = stack.pop(2)
stack << a - b
when '*'
a, b = stack.pop(2)
stack << a * b
when '/'
a, b = stack.pop(2)
stack << a / b
end
end
```

Note that Ruby's `pop`

method takes an optional argument for how many you want to pop. In your case you want two, so you can just ask for that.

Now you get this:

```
calc('23+4*')
# => 20
calc('82/')
# => 4
```

Now there's a lot of repetition in this code, so it can be boiled down to even less if you embrace Ruby's dynamic programming possibilities:

```
def calc(input)
stack = [ ]
input.chars.each do |c|
case (c)
when /[0-9]/
stack << c.to_i
when '+', '-', '*', '/'
# Combine the last two entries using the method named by
# the character.
stack << stack.pop(2).reduce(c)
end
end
stack[0]
end
```

In Ruby `a.send(:+, b)`

is the same as `a+b`

so you can often use tools like `reduce`

to apply an arbitrary operation on a set of things.