Каков приоритет вызовов методов с круглыми скобками и без них?

предыдущие ответы

на ответ на аналогичную вопрос - это неправильно.

вызовы методов не упоминаются ни в 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, postfix if, 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.