Is there better way to replace these case statement?
case cmd
when /^Astro$/
toolName = ‘astro’
when /^core/
toolName = 'coretools'
when /^(fm_shell|formality)$/
toolName = 'fm'
when /^gca_shell$/
toolName = 'gcas'
......
when /^xa/
toolName = 'xa'
else
toolName = ''
end
previn
December 20, 2013, 12:03pm
2
Not perfect, but something you could start with:
result = cmd[ /\A(astro|core|fm_shell|formality|gca_shell|xa)\z/i, 1 ]
previn
December 20, 2013, 12:10pm
3
Joel P. wrote in post #1131246:
Not perfect, but something you could start with:
result = cmd[ /\A(astro|core|fm_shell|formality|gca_shell|xa)\z/i, 1 ]
Hi Joel,
How to go on with this and set toolName accordingly? Could you please
give an
example? Thanks.
Previn
previn
December 20, 2013, 12:18pm
4
I see it’s better don’t use long case statement in book of
“Refactoring”, is there good way to do refactor on case statement with
regular expression?
previn
December 20, 2013, 12:48pm
5
Once you’ve got the return you can do any substitutions required for
your special name:
cmd = ‘fm_shell’
=> “fm_shell”
toolName = cmd[/\A(astro|core|fm_shell|formality|gca_shell|xa)\z/i, 1 ]
=> “fm_shell”
subs = { ‘fm’ => [ ‘fm_shell’, ‘formality’ ], ‘gcas’ => [ ‘gca_shell’ ]
}
=> {“fm”=>[“fm_shell”, “formality”], “gcas”=>[“gca_shell”]}
subs.each { |output, input| toolName = output if input.include? toolName
}
=> {“fm”=>[“fm_shell”, “formality”], “gcas”=>[“gca_shell”]}
toolName
=> “fm”
previn
December 20, 2013, 12:38pm
6
Can we do like the way below? But how to process the Regular express in
our case?
def eat(fruit_code)
fruit_type =
case fruit_code
when ‘a’
Apple
when ‘b’
Banana
when ‘c’
Coconut
when ‘o’
Orange
end
end
=>
FRUIT_TYPES=
{ ‘a’ => Apple, ‘b’ => Banana, ‘c’ => Coconut, ‘o’ => Orange }.
freeze
def eat(fruit_code)
fruit_type = FRUIT_TYPES[fruit_code]
end
previn
December 20, 2013, 12:54pm
7
Previn,
if you want a flexible solution, I’d go with an hash. Key is the tool
name, value is an array of regexps.
tools = {
“astro” => [ /astro/ ],
“fm” => [ /fm_shell/, /formality/ ]
}
You can then iterate over all values, see what matches the string you’ve
got, and use the key as toolName
HTH.
previn
December 20, 2013, 1:00pm
8
Previn L. wrote in post #1131257:
Can we do like the way below? But how to process the Regular express in
our case?
def eat(fruit_code)
fruit_type =
case fruit_code
when ‘a’
Apple
when ‘b’
Banana
when ‘c’
Coconut
when ‘o’
Orange
end
end
=>
FRUIT_TYPES=
{ ‘a’ => Apple, ‘b’ => Banana, ‘c’ => Coconut, ‘o’ => Orange }.
freeze
def eat(fruit_code)
fruit_type = FRUIT_TYPES[fruit_code]
end
If you want to do this with Regexp here’s one option:
types = {
astro: ‘astro’,
core: ‘coretools’,
fm_shell: ‘fm’,
formality: ‘fm’,
gca_shell: ‘gcas’,
xa: ‘xa’
}
toolName = cmd.match( /\A(#{ types.keys.join(’|’) })\z/ ) { |s|
types[s.captures.first.to_sym] }
previn
December 20, 2013, 9:11pm
9
cmd=“Astro”
#decode
code_book={ Astro: “astro”, core: “coretools”, fm_shell: “fm”,
formality: “fm” }
tool_name = code_book[cmd.to_sym]
#output
puts tool_name
The downside I see here is it returns nil instead of “” if there is no
matching.
J.T
previn
December 20, 2013, 9:15pm
10
BTW the code_book={ Astro: “astro”, core: “coretools”, fm_shell: “fm”,
formality: “fm” } works in 2.0 (or 1.9)?
I am new to Ruby, using the latest
code_book={ Astro: “astro”, core: “coretools”, fm_shell: “fm”,
formality: “fm” }
tool_name = code_book[cmd.to_sym]
J.T
previn
December 21, 2013, 5:58pm
11
Jason T. wrote in post #1131307:
tool_name = code_book[cmd.to_sym]
The downside I see here is it returns nil instead of “” if there is no
matching.
There’s this option:
tool_name = code_book[cmd.to_sym] || ‘’
previn
December 21, 2013, 5:18am
12
On 12/20/2013 02:57 AM, Previn L. wrote:
toolName = 'fm'
end
class Tool
attr_reader :name, :pat
def initialize name, pat
@name = name
@pat = pat
end
def === cmd
@pat === cmd
end
end
astro = Tool.new ‘astro’, /^Astro$/
core = Tool.new ‘coretools’, /^core/
fm = Tool.new ‘fm’, /^(fm_shell|formality)$/
gcas = Tool.new ‘gcas’, /^gca_shell$/
tools = [astro, core, fm, gcas]
cmd = “corezap”
puts tools.find {|tool| tool === cmd}.name
cmd = “gca_shell”
case cmd # there is a special relationship between case and #===
when astro; puts “doing astro stuff”
when gcas; puts “doing gcas stuff”
end
previn
December 21, 2013, 10:25pm
13
On 20/12/2013, at 11:57 PM, Previn L. [email protected] wrote:
Is there better way to replace these case statement?
Learn about polymorphism.
Henry
previn
December 21, 2013, 11:20pm
14
Can it be more ugly? It is faster though
p code_book[code_book.index {|x| cmd=~x[0]}][1]
J.T
previn
December 21, 2013, 10:21pm
15
Thanks Joel. Just noticed not every reg has ‘$’ in the end. The
following code should work the same as the ‘case/when’:
#the last one is the default
code_book=[ [/^Astro$/, ‘Astro’], [/^core/, ‘coretools’],
[/^(fm_shell|formality)$/, ‘fm’], [/^gca_shell$/, ‘gcas’], [/^xa/,
‘xa’], [/.*/, ‘’]]
cmd=gets.chomp
p code_book.collect { |reg, tool_name| tool_name if cmd =~
reg}.compact.shift
Downside is it will not break after find the first match, bright side is
you can catch if multiple matches exist.
J.T
previn
December 22, 2013, 2:37am
16
Henry M. wrote in post #1131382:
Learn about polymorphism.
Henry
This is the solution in the book of “Refactoring”, but how to implement
it here with regular expression used?
previn
December 22, 2013, 8:11pm
17
On 12/21/2013 05:13 PM, Previn L. wrote:
it, would you give more help if needed?
Please do ask. Happy to help…
previn
December 22, 2013, 9:41pm
18
Joel P. wrote in post #1131366:
Jason T. wrote in post #1131307:
tool_name = code_book[cmd.to_sym]
The downside I see here is it returns nil instead of “” if there is no
matching.
There’s this option:
tool_name = code_book[cmd.to_sym] || ‘’
I can’t believe I missed this obvious option
Hash.new ‘’
or
Hash.new { |hash, key| hash[key]=’’ }
previn
December 22, 2013, 2:13am
19
Dear Joel, Eric, Jason, Joel(VanderWerf),
Thank you so much for your warm help, with your guide, I can use hash
method to replace case statement succesfully.
Yes, as Jason noticed, for this case, reg. needed, and not every reg has
‘$’ in the end. Also thanks Eric’s solution, I know the first time how
to use reg in the hash.
I still not fully understand Joel VanderWerf’s method, I’ll go on study
it, would you give more help if needed?
previn
December 23, 2013, 10:23am
20
Nice, I’d never used fetch before. That opens up a whole host of
possibilities.