在嵌套的[:a,:b] .each {loops}中可以避免eval吗?

时间:2014-11-05 10:00:37

标签: ruby eval

有没有办法使用原生ruby方法或者图书馆来做我刚刚做的事情。我发现了关于eval的问题,我很清楚我是否能够轻松实现我的解决方案。

我知道eval并不理想,因为任意代码注入的危险。我不认为这个计划会发生,但我总是喜欢安全。

我的第一个想法是使用树形结构,但这不起作用,因为我对树木知之甚少以及如何迭代它们。我也尝试了嵌套哈希,但最后使用eval来填充它,我仍然需要弄清楚如何迭代它。

#!/usr/bin/env ruby
# This programs generates guesses for forgoten passwords
guesses   = []
passwords = []

# Read user input and generate a series of guesses.
nth = 1
print "Guess number 1:"

while guess = gets
    nth += 1
    print "Guess number #{nth}:"
    guesses << guess.chomp.split('')
end

# Generate an expression by dequeuing guesses.
first_string    = ""                
second_string   = "passwords << ''" 
letter          = 101               # First ASCII character
counter = 0

guesses.count.times do 

    # Dequeuing
    shifted_array   =   guesses.shift

    # FIFO loops
    first_string    +=  "#{shifted_array}.each{ |#{letter.chr}| "

    # Concatenates each of the permutations of the guesses
    second_string   +=  ".+(#{letter.chr})"

    letter          += 1 # Next ASCII character
    counter         += 1
end

# Adds ending braces
final_string = first_string + second_string + ('}'*counter)

# Evaluates string populating passwords array
print "\n"
eval final_string


passwords.each{|x| puts x }

2 个答案:

答案 0 :(得分:1)

Enumerables相当强大,值得学习。如果我正确理解你的问题,这也会做同样的事情:

$stdin.each_line
      .map { |guess| guess.chomp.chars }
      .inject(&:product)
      .each { |pass| puts pass.join }

答案 1 :(得分:0)

信不信由你,将变量设置为初始值,然后在循环中处理它是Ruby中的代码味道。也就是说,这表明你可能走错了路。

看一下方法&#34; map&#34;并且&#34;减少&#34;对于初学者。如果你理解它们,请寻找函数式编程的基本介绍。

一些简单的例子:

[1, 2, 3].map {|x| x + 1 }       # -> [2,3,4]
[1, 2, 3].reduce {|x,m| m += x}  # -> 6

然后,如果你掌握了这一点,也可以看看lambdas,但是你可以通过使用map来解决这个问题。

另外,请将代码分解为不同的离散作业,并使每个作业都成为一个功能。您的代码会更长一些,但很多更容易处理。