For example, I found the method name bundler?
in the following snippet, and don't know whether the ?
character is a specialized keyword or just part of the method name.
例如,我找到了方法名称bundler?在下面的片段中,不知道是否?字符是专门的关键字,或者只是方法名的一部分。
# This is a predicate useful for the doc:guides task of applications.
def bundler?
# Note that rake sets the cwd to the one that contains the Rakefile
# being executed.
File.exists?('Gemfile')
end
5 个解决方案
#1
72
Method names in Ruby may contain upper-case and lower-case letters, numbers, underscores _
and the punctation signs !
, ?
, =
.
Ruby中的方法名可能包含大写和小写字母、数字、下划线_和戳记符号!
A method name can't begin with a number, and the characters !
, ?
and =
can only appear at the end.
方法名不能以数字和字符开头!和=只能出现在末尾。
Non-ASCII characters can be used in a method name, but this can lead to very confusing situations and should not be common practice.
非ascii字符可以在方法名中使用,但是这会导致非常混乱的情况,不应该是常见的做法。
It's good practice, while not mandatory, to start the method name with a lower-case character, because names that start with capital letters are constants in Ruby. It's still possible to use a constant name for a method, but you won't be able to invoke it without parentheses, because the interpeter will look-up for the name as a constant:
使用小写字符启动方法名是很好的做法,虽然不是强制的,因为以大写字母开头的名称在Ruby中是常量。仍然可以为方法使用一个常量名称,但是如果没有括号,您将无法调用它,因为interpeter将查找这个名称作为一个常量:
def Capital
nil
end
Capital # NameError: uninitialized constant Capital
Capital() # => nil
Some very widely and consistently used conventions when defining method names are:
在定义方法名称时,一些非常广泛和一致使用的约定是:
-
Method names are full down-case, with underscores
_
as separators for words into the name (e.g.Math::sqrt
,Array#each_index
, ...).方法名是全小写的,下划线_作为单词在名称中的分隔符(例如:sqrt,数组#each_index,…)。
-
Predicates have a question mark
?
as last character (e.g.Array#empty?
,Hash#has_key?
, ...). While predicates usually return boolean values, this is not always the case: these methods just need to returnnil
orfalse
if the predicate evaluates to false, any other value otherwise (e.g.File::size?
returnsnil
if the file does not exist, the size of the file as anInteger
otherwise).谓词有问号?作为最后一个字符(例如,数组#为空?散列# has_key ?,……)。虽然谓词通常返回布尔值,但情况并不总是这样:如果谓词计算为false,那么这些方法只需要返回nil或false,否则还有其他值(例如File: size?如果文件不存在,则返回nil,否则文件的大小将为整数。
-
Methods that modify the state of the object on which they are invoked, or that have an unusual behavior have an exclamation mark
!
as last character; this methods are sometimes called mutators because they usually are destructive or in-place versions of other methods (e.g.Array#sort!
,Array#slice!
, ...).方法修改被调用对象的状态,或者具有异常行为的方法有感叹号!作为最后的字符;这种方法有时被称为mutators,因为它们通常是其他方法的破坏性或就地版本(例如数组#排序!),数组#片!,……)。
-
Setters have an equal sign
=
as last character (e.g.Array#[]=
, ...); the Ruby interpeter offers syntactic sugar for invokation of setter methods:setter有一个等号=作为最后一个字符(例如,Array#[]=,…);Ruby interpeter为调用setter方法提供语法糖:
a = [4, 5, 6] a[0] = 3 # Shorthand for a.[]=(0, 3)
Ruby also allows to define operators using the operator symbol as the method name:
Ruby还允许使用操作符符号作为方法名来定义操作符:
╔═══════════════════════════╦═════════════════════════════════════════════╦═══════╗
║ Operators (by precedence) ║ Operations ║ Arity ║
╠═══════════════════════════╬═════════════════════════════════════════════╬═══════╣
║ ! ~ + ║ Boolean NOT, bitwise complement, unary plus ║ 1 ║
║ ║ (define with method name +@, Ruby 1.9+) ║ ║
║ ║ ║ ║
║ ** ║ Exponentiation ║ 2 ║
║ ║ ║ ║
║ - ║ Unary minus (define with method name -@) ║ 1 ║
║ ║ ║ ║
║ * / % ║ Multiplication, division, modulo ║ 2 ║
║ ║ ║ ║
║ + - ║ Addition, subtraction ║ 2 ║
║ ║ ║ ║
║ << >> ║ Bitwise shift ║ 2 ║
║ ║ ║ ║
║ & ║ Bitwise AND ║ 2 ║
║ ║ ║ ║
║ | ^ ║ Bitwise OR, Bitwise XOR ║ 2 ║
║ ║ ║ ║
║ < <= => > ║ Ordering ║ 2 ║
║ ║ ║ ║
║ == === != =~ !~ <=> ║ Equality, pattern matching, comparison ║ 2 ║
╚═══════════════════════════╩═════════════════════════════════════════════╩═══════╝
Unary operator methods are passed no arguments; binary operator methods are passed an argument, and operate on it and on self
.
无参数传递一元运算符方法;二进制运算符方法被传递一个参数,并对它和self进行操作。
It's important to adhere strictly to the arity of the operators; while it is possible to define operator methods with a different arity (e.g. a +
method that takes two arguments), Ruby would not allow you to call the method with operator syntax (it would however work with dot syntax).
严格遵守操作符的多样性是很重要的;虽然可以用不同的特性定义操作符方法(例如,使用两个参数的+方法),但是Ruby不允许使用操作符语法调用该方法(但是它会使用点语法)。
It's good practice to adhere to the original semantics of the operators as much as possible: it should be intuitive to someone who knows the original meaning of the operator how it works with user defined classes.
尽可能坚持操作符的原始语义是一种很好的实践:对于知道操作符的原始含义的人来说,它应该是直观的,因为它是如何与用户定义的类一起工作的。
The language also offers syntactic sugar for the special, non-operator ,[]
method that is normally used for accessing array and hash values. The []
method can be defined with arbitrary arity.
该语言还为特殊的、非操作符的[]方法提供语法糖,该方法通常用于访问数组和散列值。[]方法可以任意定义。
For every binary operator in the table, except ordering, equality, comparison and pattern matching, Ruby also offers shorthand for abbreviated assignment (e.g. x += y
expands to x = x + y
); you can't define them as methods, but you can alter their behavior defining the operators on which they're based.
对于表中的每个二进制运算符,除了排序、相等、比较和模式匹配之外,Ruby还提供了缩写赋值(例如x += y展开为x = x + y);不能将它们定义为方法,但是可以改变它们的行为,定义它们所基于的操作符。
None of these characters can be used inside normal method names (e.g. do&print
or start-up
are not valid method names).
这些字符都不能在普通方法名称中使用(例如,do&print或start不是有效的方法名称)。
#2
4
What others say is true for the built-in syntax, however there seems to be no back-end restrictions on what can be used if you use methods like define_method
+ send
:
其他人说的对内置语法来说是正确的,但是如果你使用define_method + send这样的方法,似乎没有后端限制可以使用什么:
define_method(:'$% ^&') { 0 }
define_method(:'你好') { 1 }
send(:'$% ^&') == 0 or raise
send(:'你好') == 1 or raise
This fact can be useful: for example Rails' ActiveSupport::Testing::Declarative.test method uses it so as not to do complex conversions on:
这个事实可能很有用:例如,Rails的ActiveSupport:::Testing:声明性。测试方法使用它,以避免进行复杂的转换:
test 'Some Controller#Method' do
to a saner name, which might conflict with another test named:
以更合理的名称命名,这可能与另一个命名为:
test 'Some Controller_Method' do
This is mentioned on the Testing Guide.
测试指南中提到了这一点。
Curiosity: a similar thing happens in Java, where the bytecode method name gives way more choice than the Java language: Why does the JVM allow us to name a function starting with a digit in bytecode?
好奇心:在Java中也发生了类似的事情,字节码方法名提供了比Java语言更多的选择:为什么JVM允许我们以字节码开头的数字命名函数?
#3
2
Method names can end in !
, ?
or =
. Underscores are allowed as well. Besides that there are several methods that look like operators (e.g. +
, *
, >>
, []
) that you can define for your own classes.
方法名可以以!或=。下划线也是允许的。此外,还有一些方法看起来像操作符(例如+、*、>>、[]),您可以为自己的类定义它们。
#4
2
To add one thing: you can also tell an object to run a method with no name at all and it will try to invoke a method named call
:
要添加一个东西:您还可以告诉对象运行一个没有名称的方法,它将尝试调用一个名为call的方法:
#!/usr/bin/env ruby
class Foo
=begin
def call(*args)
puts "received call with #{args.join(' ')}"
end
=end
def method_missing(m, *args, &block)
puts "received method_missing on `#{m}(#{args.join(', ')})`"
end
end
f = Foo.new
f.('hi') # Not a syntax error! method_missing with m of :call
f.send :'', 'hmm' # method_missing with m set to :''
f.send nil, 'bye' # raises an error
There is not actually any method named call
defined on Object
, but there is one on the Method
and Proc
classes.
实际上,在对象上没有定义任何名为call的方法,但是在方法和Proc类上有一个方法。
In some languages ()
is an operator for function invocation, and that seems pretty similar to what's happening here.
在某些语言中()是函数调用的操作符,这与这里所发生的非常相似。
This is used e.g. in Rails' JBuilder:
例如,在Rails的JBuilder中使用:
https://github.com/rails/jbuilder
https://github.com/rails/jbuilder
It is documented on page 196 of the O'Reilly Ruby book:
在O'Reilly Ruby书第196页有记录:
Ruby 1.9 offers an additional way to invoke a
Proc
object; as an alternative to square brackets, you can use parentheses prefixed with a period:Ruby 1.9提供了另一种调用Proc对象的方法;作为方括号的替代方法,可以使用带句号的圆括号:
z = f.(x,y)
.()
looks like a method invocation missing the method name. This is not an operator that can be defined, but rather is syntactic-sugar that invokes thecall
method. It can be used with any object that defines acall
method and is not limited toProc
objects..()看起来像一个缺少方法名的方法调用。这不是可以定义的操作符,而是调用调用call方法的语法糖。它可以用于任何定义调用方法且不限于Proc对象的对象。
#5
0
The characters allowed are: a-Z,
, 0-9
as long as not at the beginning, _
, and ?
(for boolean functions) and !
(for destructive functions) and =
(for setters).
允许的字符是:a-Z, 0-9,只要不是在开头,_和?(对于布尔函数)和!(用于破坏性函数)和=(用于setter)。
#1
72
Method names in Ruby may contain upper-case and lower-case letters, numbers, underscores _
and the punctation signs !
, ?
, =
.
Ruby中的方法名可能包含大写和小写字母、数字、下划线_和戳记符号!
A method name can't begin with a number, and the characters !
, ?
and =
can only appear at the end.
方法名不能以数字和字符开头!和=只能出现在末尾。
Non-ASCII characters can be used in a method name, but this can lead to very confusing situations and should not be common practice.
非ascii字符可以在方法名中使用,但是这会导致非常混乱的情况,不应该是常见的做法。
It's good practice, while not mandatory, to start the method name with a lower-case character, because names that start with capital letters are constants in Ruby. It's still possible to use a constant name for a method, but you won't be able to invoke it without parentheses, because the interpeter will look-up for the name as a constant:
使用小写字符启动方法名是很好的做法,虽然不是强制的,因为以大写字母开头的名称在Ruby中是常量。仍然可以为方法使用一个常量名称,但是如果没有括号,您将无法调用它,因为interpeter将查找这个名称作为一个常量:
def Capital
nil
end
Capital # NameError: uninitialized constant Capital
Capital() # => nil
Some very widely and consistently used conventions when defining method names are:
在定义方法名称时,一些非常广泛和一致使用的约定是:
-
Method names are full down-case, with underscores
_
as separators for words into the name (e.g.Math::sqrt
,Array#each_index
, ...).方法名是全小写的,下划线_作为单词在名称中的分隔符(例如:sqrt,数组#each_index,…)。
-
Predicates have a question mark
?
as last character (e.g.Array#empty?
,Hash#has_key?
, ...). While predicates usually return boolean values, this is not always the case: these methods just need to returnnil
orfalse
if the predicate evaluates to false, any other value otherwise (e.g.File::size?
returnsnil
if the file does not exist, the size of the file as anInteger
otherwise).谓词有问号?作为最后一个字符(例如,数组#为空?散列# has_key ?,……)。虽然谓词通常返回布尔值,但情况并不总是这样:如果谓词计算为false,那么这些方法只需要返回nil或false,否则还有其他值(例如File: size?如果文件不存在,则返回nil,否则文件的大小将为整数。
-
Methods that modify the state of the object on which they are invoked, or that have an unusual behavior have an exclamation mark
!
as last character; this methods are sometimes called mutators because they usually are destructive or in-place versions of other methods (e.g.Array#sort!
,Array#slice!
, ...).方法修改被调用对象的状态,或者具有异常行为的方法有感叹号!作为最后的字符;这种方法有时被称为mutators,因为它们通常是其他方法的破坏性或就地版本(例如数组#排序!),数组#片!,……)。
-
Setters have an equal sign
=
as last character (e.g.Array#[]=
, ...); the Ruby interpeter offers syntactic sugar for invokation of setter methods:setter有一个等号=作为最后一个字符(例如,Array#[]=,…);Ruby interpeter为调用setter方法提供语法糖:
a = [4, 5, 6] a[0] = 3 # Shorthand for a.[]=(0, 3)
Ruby also allows to define operators using the operator symbol as the method name:
Ruby还允许使用操作符符号作为方法名来定义操作符:
╔═══════════════════════════╦═════════════════════════════════════════════╦═══════╗
║ Operators (by precedence) ║ Operations ║ Arity ║
╠═══════════════════════════╬═════════════════════════════════════════════╬═══════╣
║ ! ~ + ║ Boolean NOT, bitwise complement, unary plus ║ 1 ║
║ ║ (define with method name +@, Ruby 1.9+) ║ ║
║ ║ ║ ║
║ ** ║ Exponentiation ║ 2 ║
║ ║ ║ ║
║ - ║ Unary minus (define with method name -@) ║ 1 ║
║ ║ ║ ║
║ * / % ║ Multiplication, division, modulo ║ 2 ║
║ ║ ║ ║
║ + - ║ Addition, subtraction ║ 2 ║
║ ║ ║ ║
║ << >> ║ Bitwise shift ║ 2 ║
║ ║ ║ ║
║ & ║ Bitwise AND ║ 2 ║
║ ║ ║ ║
║ | ^ ║ Bitwise OR, Bitwise XOR ║ 2 ║
║ ║ ║ ║
║ < <= => > ║ Ordering ║ 2 ║
║ ║ ║ ║
║ == === != =~ !~ <=> ║ Equality, pattern matching, comparison ║ 2 ║
╚═══════════════════════════╩═════════════════════════════════════════════╩═══════╝
Unary operator methods are passed no arguments; binary operator methods are passed an argument, and operate on it and on self
.
无参数传递一元运算符方法;二进制运算符方法被传递一个参数,并对它和self进行操作。
It's important to adhere strictly to the arity of the operators; while it is possible to define operator methods with a different arity (e.g. a +
method that takes two arguments), Ruby would not allow you to call the method with operator syntax (it would however work with dot syntax).
严格遵守操作符的多样性是很重要的;虽然可以用不同的特性定义操作符方法(例如,使用两个参数的+方法),但是Ruby不允许使用操作符语法调用该方法(但是它会使用点语法)。
It's good practice to adhere to the original semantics of the operators as much as possible: it should be intuitive to someone who knows the original meaning of the operator how it works with user defined classes.
尽可能坚持操作符的原始语义是一种很好的实践:对于知道操作符的原始含义的人来说,它应该是直观的,因为它是如何与用户定义的类一起工作的。
The language also offers syntactic sugar for the special, non-operator ,[]
method that is normally used for accessing array and hash values. The []
method can be defined with arbitrary arity.
该语言还为特殊的、非操作符的[]方法提供语法糖,该方法通常用于访问数组和散列值。[]方法可以任意定义。
For every binary operator in the table, except ordering, equality, comparison and pattern matching, Ruby also offers shorthand for abbreviated assignment (e.g. x += y
expands to x = x + y
); you can't define them as methods, but you can alter their behavior defining the operators on which they're based.
对于表中的每个二进制运算符,除了排序、相等、比较和模式匹配之外,Ruby还提供了缩写赋值(例如x += y展开为x = x + y);不能将它们定义为方法,但是可以改变它们的行为,定义它们所基于的操作符。
None of these characters can be used inside normal method names (e.g. do&print
or start-up
are not valid method names).
这些字符都不能在普通方法名称中使用(例如,do&print或start不是有效的方法名称)。
#2
4
What others say is true for the built-in syntax, however there seems to be no back-end restrictions on what can be used if you use methods like define_method
+ send
:
其他人说的对内置语法来说是正确的,但是如果你使用define_method + send这样的方法,似乎没有后端限制可以使用什么:
define_method(:'$% ^&') { 0 }
define_method(:'你好') { 1 }
send(:'$% ^&') == 0 or raise
send(:'你好') == 1 or raise
This fact can be useful: for example Rails' ActiveSupport::Testing::Declarative.test method uses it so as not to do complex conversions on:
这个事实可能很有用:例如,Rails的ActiveSupport:::Testing:声明性。测试方法使用它,以避免进行复杂的转换:
test 'Some Controller#Method' do
to a saner name, which might conflict with another test named:
以更合理的名称命名,这可能与另一个命名为:
test 'Some Controller_Method' do
This is mentioned on the Testing Guide.
测试指南中提到了这一点。
Curiosity: a similar thing happens in Java, where the bytecode method name gives way more choice than the Java language: Why does the JVM allow us to name a function starting with a digit in bytecode?
好奇心:在Java中也发生了类似的事情,字节码方法名提供了比Java语言更多的选择:为什么JVM允许我们以字节码开头的数字命名函数?
#3
2
Method names can end in !
, ?
or =
. Underscores are allowed as well. Besides that there are several methods that look like operators (e.g. +
, *
, >>
, []
) that you can define for your own classes.
方法名可以以!或=。下划线也是允许的。此外,还有一些方法看起来像操作符(例如+、*、>>、[]),您可以为自己的类定义它们。
#4
2
To add one thing: you can also tell an object to run a method with no name at all and it will try to invoke a method named call
:
要添加一个东西:您还可以告诉对象运行一个没有名称的方法,它将尝试调用一个名为call的方法:
#!/usr/bin/env ruby
class Foo
=begin
def call(*args)
puts "received call with #{args.join(' ')}"
end
=end
def method_missing(m, *args, &block)
puts "received method_missing on `#{m}(#{args.join(', ')})`"
end
end
f = Foo.new
f.('hi') # Not a syntax error! method_missing with m of :call
f.send :'', 'hmm' # method_missing with m set to :''
f.send nil, 'bye' # raises an error
There is not actually any method named call
defined on Object
, but there is one on the Method
and Proc
classes.
实际上,在对象上没有定义任何名为call的方法,但是在方法和Proc类上有一个方法。
In some languages ()
is an operator for function invocation, and that seems pretty similar to what's happening here.
在某些语言中()是函数调用的操作符,这与这里所发生的非常相似。
This is used e.g. in Rails' JBuilder:
例如,在Rails的JBuilder中使用:
https://github.com/rails/jbuilder
https://github.com/rails/jbuilder
It is documented on page 196 of the O'Reilly Ruby book:
在O'Reilly Ruby书第196页有记录:
Ruby 1.9 offers an additional way to invoke a
Proc
object; as an alternative to square brackets, you can use parentheses prefixed with a period:Ruby 1.9提供了另一种调用Proc对象的方法;作为方括号的替代方法,可以使用带句号的圆括号:
z = f.(x,y)
.()
looks like a method invocation missing the method name. This is not an operator that can be defined, but rather is syntactic-sugar that invokes thecall
method. It can be used with any object that defines acall
method and is not limited toProc
objects..()看起来像一个缺少方法名的方法调用。这不是可以定义的操作符,而是调用调用call方法的语法糖。它可以用于任何定义调用方法且不限于Proc对象的对象。
#5
0
The characters allowed are: a-Z,
, 0-9
as long as not at the beginning, _
, and ?
(for boolean functions) and !
(for destructive functions) and =
(for setters).
允许的字符是:a-Z, 0-9,只要不是在开头,_和?(对于布尔函数)和!(用于破坏性函数)和=(用于setter)。