什么类型的名称对Ruby方法合法?

时间:2014-06-09 05:30:32

标签: ruby methods

this article中,它使用以下方法。

h = {}
def h.[]=(k, v)
  puts "Setting hash key #{k} with #{v.inspect}"
  super
end

# 1. The standard ||= approach
h[:x] ||= 10
h[:x] ||= 20
...

我知道这是=( )部分的这样的制定者。

def noise=(noise)
  @noise = noise
end

Q1。但我不确定.[]部分在做什么。

Q2。你可以在Ruby方法名中使用[]或其他非字母表吗?

2 个答案:

答案 0 :(得分:5)

  

Q1。但我不确定是什么。[]部分正在做。

几乎所有东西都是Ruby中的对象,我们可以在任何对象上定义一个方法。所以[]=是Ruby中Hash类(一个对象)定义的方法,就像+-是数字(也是对象)的方法一样:

> 4 + 5
# => 9

> 4.+(5)
# => 9

> 10.-(3)
# => 7

同样,我们可以为定义它的对象调用.[].[]=方法,如数组:

> arr = ['hi', 'there', 'welcome', 'to', 'StackOverflow']
> arr.[](3)
# => "to"

或者喜欢你的哈希:

> hash = {:name => 'Bob', :age => 27}
> hash[:name]
# => "Bob"

> hash[:name] = 'Steve'
# => "Steve"

同样,Ruby允许我们将方法放在任何对象上,并且(几乎)所有东西都是Ruby中的对象。因此,我们可以在我们喜欢的任何类上定义.[]方法:

> class Foo
>   def [](arg)
>     arg
>   end
> end
> Foo.new[456]
> # => 456

由于对象的实例也是对象,我们可以将该方法定义为仅在特定实例上:

> h = {}           # a Hash instance
> def h.[](arg)    # we're giving this instance a new method
>   "received #{arg}"
> end
> h[123]
# => "received 123"

同一个类的其他实例将无法实现该实现:

> {:foo => :bar}[123]   # other Hash instances don't have this method,
                        # so they're using the default Hash#[] method
# => nil

.[]在某个方面属于特殊情况,因为我们让你跳过括号并将参数放在括号内:

> arr[3] == arr.[](3)
# => true
  

Q2。你可以在Ruby方法名中使用[]或其他非字母表吗?

不,您不能在任意Ruby方法的名称中使用[]。这是一个运算符(如上例中的+-)。

您只能重载特定的运算符,即(按优先顺序列出):

  • !~+(一元)
  • **
  • -(一元)
  • */%
  • +-(二进制)
  • <<>>
  • &
  • |^
  • <<==>>
  • =====!==~!~<=>

否则,Ruby方法可以包含字母数字Unicode字符和下划线的任何混合。 (我在这里松散地使用“字母数字” - Ruby在它允许的内容中非常自由,并且一般来说,任何未被语言保留以标记事物的字符都会起作用。)它可以选择以单个 !?,它可能不会以数字开头。

所以这些是有效的方法名称:

  • present?
  • valid_user?
  • replace!
  • replace
  • 更换(但您可能应该使用A-Z拉丁字母表制作您的方法名称,以便开发人员不要讨厌您)
  • ❨╯°□°❩╯︵┻━┻
  • ┬─┬ノ❨º_ºノ❩
  • replace_all

  • REPLACE_1

  • REPLACE_ALL

请注意,虽然最后两个是有效的方法名称,但按照惯例,Rubyists通常为常量保留ALL-CAPS标识符,而不是方法。

答案 1 :(得分:1)

在Ruby中,[][]=只是运算符,可以重载。

此处[]=正在h的单例类中定义,换句话说,它被定义为仅针对h以某种方式工作。

所以当你说h[something] = somethingelse新方法被调用时。

你这是正确的,这与使用setter的一般用法非常相似。

要回答第二个问题,您可以重复显示in this table所显示的运算符,但您无法继续像某些语言一样创建<-*->之类的运算符。