2013-05-27 40 views
1

嗨我想知道是否有人可以向我解释为什么写在下面的代码中的地图函数是写在它的书面方式。具体为什么我们需要做的在中间步骤的局部变量

results = letters.map do |letter| encrypted_letter = encrypt_letter(letter) 

,而不是仅仅做

results = letters.map do |letter| encrypt_letter(letter) 

class Encryptor 
    def cipher 
    {"a" => "n", "b" => "o", 'c' => 'p', 'd' => 'q', 
      'e' => 'r', 'f' => 's', 'g' => 't', 'h' => 'u', 
     'i' => 'v', 'j' => 'w', 'k' => 'x', 'l' => 'y', 
     'm' => 'z', 'n' => 'a', 'o' => 'b', 'p' => 'c', 
     'q' => 'd', 'r' => 'e', 's' => 'f', 't' => 'g', 
     'u' => 'h', 'v' => 'i', 'w' => 'j', 'x' => 'k', 
     'y' => 'l', 'z' => 'm'} 
    end 

    def encrypt_letter(letter) 
     lowercase_letter = letter.downcase 
     cipher[lowercase_letter] 
    end 

    def encrypt(string) 
     letters = string.split("") 
     results = letters.map do |letter| 
      encrypted_letter = encrypt_letter(letter) 
     end 
     results.join 
    end 

    def decrypt_letter(letter) 
     lowercase_letter = letter.downcase 
     cipher.key(lowercase_letter) 
    end 

    def decrypt(string) 
     letters = string.split("") 
     results = letters.map do |letter| 
     decrypted_letter = decrypt_letter(letter) 
     end 

     results.join 
    end 

end 

回答

0

有没有为它功能上的原因。有时程序员觉得他们的结果有一个明确的变量目的地,因此更加舒适。也许这是其中的一种情况。与解密的信件一样。

+0

好,谢谢。我试图弄清楚它的相当一段时间 – JaTo

+2

“有时程序员觉得他们的结果有一个明确的变量目的地,更舒服。”?我会更简单地说:写它的人不知道“地图”是如何工作的,而且写得过于冗长。中间变量有它们的位置,但不应该指定为只能使用一次。 @ Tinman ...... –

+0

......我没有任何建议,这是很好的做法。我只是在做一个观察,并且有点舌尖。我不会完全假定程序员脑子里发生了什么。 – lurker

6

没理由;该变量立即被丢弃。

我认为这是误导和不通透的。

大部分的代码似乎有点冗长,例如:

def encrypt(string) 
    letters = string.split("") 
    results = letters.map do |letter| 
     encrypted_letter = encrypt_letter(letter) 
    end 
    results.join 
end 

IMO这将是更红宝石去年秋季的东西更接近:

def encrypt(str) 
    str.chars.collect { |c| encrypt(c) }.join 
end 

这可能是比更紧,或以其他方式书写,尽管其中一些是偏好问题。例如,each_with_object可以与铲运营商一起使用,但这不太“功能性”。

(我喜欢collectmap收集时,偏好,我觉得更多的沟通,如果更长的时间。)

超多行不使事情可读的传播功能,但它依赖于上下文。 Ruby的新手或方法链可能会被(国际海事组织比较规范的)单线程混淆。

+0

伟大的答案!在哪些情况下,我应该使用“地图”更具沟通性?到目前为止,我一直只用它来收集 – JaTo

+0

@JamieS就像我说的那样,这是个人喜好 - 'map'是一个众所周知的构造,我只是在'each'的意义上找到更接近的意思,所以当我'我积极收集结果,我喜欢“收集”。我的偏好没有技术上的理由,我可能会选择少数。我只是想解释为什么我在我的例子中使用它:) –

+0

+1。同意。严密的代码是可读的,不会浪费时间完成任务。为单次使用指定一个中间值不会提高可读性,相反,这意味着不确定代码将执行什么操作,并为人工可读性带来空气,但会导致视觉混乱。 –

1

正如别人所说,它没有理由。这显然是一个初学者编写的代码。除了戴夫牛顿的观点之外,将恒定散列定义为方法cipher是一种坏习惯。每次调用代码时,都会创建一个新的散列。这对每封信都必须完成。这是一个巨大的资源浪费。

使用哈希,你可以简单地这样做:

h = {"a" => "n", "b" => "o", 'c' => 'p', 'd' => 'q', 
    'e' => 'r', 'f' => 's', 'g' => 't', 'h' => 'u', 
    'i' => 'v', 'j' => 'w', 'k' => 'x', 'l' => 'y', 
    'm' => 'z', 'n' => 'a', 'o' => 'b', 'p' => 'c', 
    'q' => 'd', 'r' => 'e', 's' => 'f', 't' => 'g', 
    'u' => 'h', 'v' => 'i', 'w' => 'j', 'x' => 'k', 
    'y' => 'l', 'z' => 'm'} 
h.default_proc = ->x{x} 

"hello world".gsub(/./, h) 
# => "uryyb jbeyq" 

但我宁愿这个去:

from = "abcdefghijklmnopqrstuvwxyz" 
to = "nopqrstuvwxyzabcdefghijklm" 

"hello world".tr(from, to) 
# => "uryyb jbeyq"