【问题标题】:Why is "300".intern valid but :300 is not为什么“300”.intern 有效但 :300 无效
【发布时间】:2014-01-27 03:55:21
【问题描述】:

我正在使用 codeacadamy.com 学习 Ruby,当前的任务是创建一个包含电影列表的哈希。所以,作为我,我投入的第一部电影是 300。

movies = {
  300: 3,
  titanic: 1,
  joe_versus_the_volcanoe: 3
}

我注意到 300 抛出了一个错误:

(ruby):1: syntax error, unexpected ':', expecting tASSOC
    300: 3,
        ^

这很有意义,但后来我尝试使用字符串。

puts "300".intern
puts "300".to_sym
puts :300

前两个是有效符号并输出 300 到屏幕,但最后一个抛出错误。我知道 300 应该出错,因为它不是以有效的方法字符开头(据我所知是 a-zA-Z_),但是 .to_sym.intern 正在做什么以使 "300" 成为有效符号?

【问题讨论】:

  • 不完全是,我理解他的问题是什么,并且实际上在做几乎完全相同的事情,但我仍然不知道为什么它会让 "300".to_sym 成为一个符号,因为符号应该开始具有有效的方法字符。
  • 从这里读取前 2 行 -ruby-doc.org/core-2.1.0/Symbol.html
  • 但是 '"300": 3' 也不起作用。但这可能只是因为 'symbol:' 语法不像 '=>' 那样充实,因为 ':"300" => 3' 工作得很好。

标签: ruby hash symbols


【解决方案1】:

您通过说puts "300".to_sym 创建的符号不是使用Fixnum 创建的符号,而是使用字符串创建的。您似乎在这里混淆了 Fixnum 与字符串。

:"300" 是一个有效的符号

:300 不是

当你输入puts "300".to_sym时,它会返回:"300"

1.9.3-p484 :002 > "300".to_sym
 => :"300" 

你可以很容易地制作你的哈希

1.9.3-p484 :013 > hsh = {
1.9.3-p484 :014 >     :"300" => 3,
1.9.3-p484 :015 >     :something_else => 2
1.9.3-p484 :016?>   }
 => {:"300"=>3, :something_else=>2} 
1.9.3-p484 :017 > hsh[:"300"]
 => 3 

这样就可以了。

如果您尝试将to_sym 发送到Fixnum,您的问题会更准确地说明。

1.9.3-p484 :018 > 300.to_sym
    NoMethodError: undefined method `to_sym' for 300:Fixnum
    from (irb):18
    from /Users/rsahae/.rvm/rubies/ruby-1.9.3-p327/bin/irb:18:in `<main>'

【讨论】:

  • 一般来说,符号遵循变量/方法名称规则,即第一个字符不能是数字。除非你使用引号,否则一切都会发生。
  • 对不起,我没有答案,我也想知道。我的猜测是它只是解释器的东西以及它如何处理特定的语法快捷方式。
  • 我认为这个答案在某种程度上歪曲了这个问题。问题不在于Fixnum 不响应to_sym,而是:300 不是符号文字的有效语法:pastebin.com/aFNua2rL
  • 我认为 OP 在帖子中承认他们理解 :300 无效。帖子的结尾是 “我知道 300 应该出错,因为它不是以有效的方法字符开头(据我所知是 a-zA-Z_),但是 .to_sym 和 .intern 在做什么使“300”成为有效符号?” 在这种情况下,我相信答案解决了所提出的问题。
【解决方案2】:

您可以在符号中放置几乎任何您想要的字符,只是不能使用符号文字的:name 语法。

"1 whole sentence with all sorts of characters!".to_sym
#=> :"1 whole sentence with all sorts of characters!"

您可以为此使用的另一种符号文字语法是:"string" 语法:

movies = {
  :"300" => 3,
  :titanic => 1,
  :joe_versus_the_volcanoe => 3
}
#=> {:"300"=>3, :titanic=>1, :joe_versus_the_volcanoe=>3}

【讨论】:

    【解决方案3】:
    puts :300
    

    不会因为不是以有效的方法字符开头而失败,而是因为 300 不是字符串而失败。 puts :"300" 确实有效。

    【讨论】:

    • 但是puts :a300 有效,而a300 本身也不是Ruby 中的字符串。
    • @Ajedi32 好点。错误消息是:syntax error, unexpected tINTEGER, expecting tSTRING_CONTENT or tSTRING_DBEG or tSTRING_DVAR or tSTRING_END,所以正确的答案可能是解释这到底是什么意思——我不知道。
    • 表示300在Ruby中不是一个有效的标识符:web.njit.edu/all_topics/Prog_Lang_Docs/html/ruby/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-26
    • 2022-01-12
    • 2020-05-14
    • 2020-10-07
    • 2023-03-30
    • 2013-05-13
    相关资源
    最近更新 更多