Каков приоритет вызовов методов с круглыми скобками и без них?
предыдущие ответы
на ответ на аналогичную вопрос - это неправильно.
вызовы методов не упоминаются ни в Ruby документация, ни в сообщество wiki.
вызов метода без скобок
выше or
or
кажется, имеют более низкий приоритет, чем вызов метода без скобок :
puts false or true
is эквивалентно
( puts false ) or true
и выводит false
.
примечание: Я знаю or
не следует использовать. Тем не менее, это хороший пример, чтобы показать, что некоторые операторы имеют более низкий приоритет, чем вызов метода.
меньше, чем ||
puts false || true
эквивалентно
puts (false || true)
и выводит true
.
вызов метода со скобками
скобки, используемые для вызова метода не группировка:
puts(false or true)
# SyntaxError: unexpected keyword_or
puts((false or true))
#=> true
вопрос
где вызовы методов без скобок в этой верх таблица?
разъяснения Баунти
Я ищу точное местоположение вызовов методов в таблице. Предпочтительно с примерами, доказывающими, что он ниже предыдущего и выше следующего.
текущие ответы также, похоже, не упоминают вызовы методов с скобки.
спасибо заранее!
3 ответов
прелюдия
это направлено на проверку всех возможных сценариев.
Примечание что когда говорят "оператором X
имеет более высокий приоритет, чем вызов метода" то, что подразумевается в аргументах. Aka:
invocation foo X bar
в отличие от (вызов на объект)
X invocation
что касается второго случая, вызовы методов всегда имеют более высокий приоритет.
короткий ответ:
это не подходит:
- вызывает
SyntaxError
в некоторых случаях - он имеет более высокий приоритет, чем
rescue
, но ниже, чем задание
резюме
-
not
не может использоваться после вызова метода, независимо от скобки - с помощью квадратных скобок (
()
) с вызовами метода иногда вызываетSyntaxError
. Эти случаи:and
,or
,if
,unless
,until
,while
иrescue
- в случаях, когда скобки не вызывают ошибки, они никоим образом не меняют приоритет
- все операторы, кроме
and
,or
, postfixif
,unless
,until
,while
,rescue
имеют более высокий приоритет, чем вызов метода
давайте попробуем это:
class Noone < BasicObject
undef_method :!
def initialize(order)
@order = order
end
def method_missing(name, *args)
@order << name
self
end
end
первый унарные:
# + and - will become binary
unary_operators = %i(! ~ not defined?)
puts 'No brackets'
unary_operators.each do |operator|
puts operator
order = []
foo = Noone.new order
bar = Noone.new order
begin
eval("foo.meta #{operator} bar")
rescue SyntaxError => e
puts e
end
p order
puts '-----------'
end
puts 'Brackets'
unary_operators.each do |operator|
puts operator
order = []
foo = Noone.new order
bar = Noone.new order
begin
eval("foo.meta(#{operator} bar)")
rescue SyntaxError => e
puts e
end
p order
puts '-----------'
end
пункты:
-
not
через способ вызов-этоSyntaxError
- все унарные операторы имеют более высокий приоритет, чем вызов метода, независимо от скобки
теперь бинарные:
binary_operators = %i(
**
* / %
+ -
<< >>
&
| ^
> >= < <=
<=> == === =~
.. ...
or and
)
puts 'No brackets'
binary_operators.each do |operator|
order = []
foo = Noone.new order
bar = Noone.new order
baz = Noone.new order
begin
eval("foo.meta bar #{operator} baz")
rescue SyntaxError => e
puts e
end
p order
end
puts 'Brackets'
binary_operators.each do |operator|
order = []
foo = Noone.new order
bar = Noone.new order
baz = Noone.new order
begin
eval("foo.meta( bar #{operator} baz)")
rescue SyntaxError => e
puts e
end
p order
end
пункты:
- скобки вокруг вызова метода с
and
илиor
этоSyntaxError
- мы должны проверить
and
иor
далее без скобок -
..
и...
вызов<=>
. Мы должны проверить это далее - мы не могли проверить несколько других двоичных операторов таким образом, а именно
&&
,||
,==
,!=
, модификаторrescue
,if
,unless
,until
,while
- кроме вышеупомянутых, операторы имеют более высокий приоритет, независимо от скобок
def yes
puts 'yes'
true
end
def no
puts 'no'
false
end
def anything(arg)
puts 'Anything'
arg
end
anything yes and no
anything no or yes
anything yes && no
anything no || yes
anything(yes && no)
anything(no || yes)
anything yes == no
anything(yes == no)
anything yes != no
anything(yes != no)
пункты:
-
and
иor
иметь более низкий приоритет, без скобок -
&&
,||
,==
и!=
имеют более высокий приоритет, независимо от скобки
def five(*args)
p args
5
end
five 2..7
five(2..7)
five 2...7
five(2...7)
пункты:
-
..
и...
имеют более высокий приоритет, независимо от скобки
anything yes if no
anything(yes if no)
anything no unless yes
anything(no unless yes)
anything no until yes
anything(no until yes)
anything yes while no
anything(yes while no)
пункты:
- скобки
if
,unless
,until
,while
вызватьSyntaxError
- все вышеперечисленное имеет более низкий приоритет, чем вызов метода без скобки
def error
puts 'Error'
raise
end
anything error rescue yes
anything(error rescue yes)
пункты:
- скобки
rescue
вызватьSyntaxError
-
rescue
имеет более низкий приоритет, если нет скобок
троичная:
anything yes ? no : 42
anything(yes ? no : 42)
пункты:
- троичный имеет более высокий приоритет, независимо от скобки
назначение (оставлено для последнего, поскольку оно изменяется yes
и no
):
anything yes = no
anything(no = five(42))
пункты:
- задание имеет более высокий приоритет, чем вызов
обратите внимание, что +=
и тому подобное-это просто ярлыки для +
и =
таким образом, они демонстрируют одинаковое поведение.
в Ruby приоритет вызова метода кажется ниже, чем defined?
но выше, чем or
.
например:
puts defined? true
#=> true
puts false or true
#=> prints `false` and returns `true`
Примечание.:
puts(not true)
и puts(false or true)
поднять синтаксических ошибок.
обновление, чтобы фактически ответить на вопрос.
официально методы не имеют приоритета. Однако, как вы продемонстрируете, мы можем отсортировать их в списке приоритетов, и они попадают между тем, что мы могли бы рассмотреть "операторы" и то, что мы могли бы рассмотреть "поток управления" ключевые слова.
смотрите,https://ruby-doc.org/core-2.2.0/doc/syntax/precedence_rdoc.html
который начинается с операторов и заканчивается конструкциями потока управления как
?, :
modifier-rescue
=, +=, -=, etc.
defined?
not
or, and
modifier-if, modifier-unless, modifier-while, modifier-until
единственный чудак есть defined?
из которых я не понимаю, почему он не был определен как глобальная функция на Kernel
модуль в любом случае.
отсутствует raise
, loop
, catch/throw
и другие?
это не ключевые слова, а вызовы методов, которые определяются как module_function
на Kernel
модуль. И так как этот модуль включен в Object
они сделаны в частные методы всех классов и поэтому кажутся глобальными функциями, доступно везде.
надеюсь, что это поможет ответить на вопрос. Извините за оригинальную copypasta.