Bug #15928

Constant declaration does not conform to JIS 3017:2013

Added by yugui (Yuki Sonoda) over 1 year ago. Updated over 1 year ago.

Target version:
ruby -v:
ruby 2.7.0dev (2019-06-16T14:01:46Z master d4929f5185) [x86_64-darwin18]


The order of evaluation in constant declaration does not conform to JIS 3017:2013


Suppose that we are evaluating the following program.

expr::C = lhs

The standard seems to be requiring the following evaluation order:

  1. expr
    • raise a TypeError if the value is not a kind of Module
  2. lhs
  3. rb_const_set(expr, :C, lhs)

However, the actual implementation evaluates in the following order

  1. lhs
  2. expr
  3. rb_const_set(expr, :C, lhs)
    • raise a TypeError if the expr is not a kind of Module

How to reproduce

The next program does not raise "recv" but raises "value"

raise("recv")::C = raise("value")

The next program does not raise a TypeError but raises a RuntimeError

A = 1
A::C = raise("value")


  • Is this interpretation of the standard correct?
  • If it is, Should we change the current behavior?
  • If we shouldn't, does it mean an issue in the standard?


Updated by chrisseaton (Chris Seaton) over 1 year ago

There are specs that cover this, so at least it is how Ruby implementors understand that it is intended to be, and it's been this way for a decade or more.

Updated by mame (Yusuke Endoh) over 1 year ago

IMO, for expr::C = lhs, it should first evaluate expr and then do lhs because expr is left to lhs. But I'm unsure whether it should raise a TypeError when expr is not a Module. My personal expectation is that lhs is evaluated and then a TypeError is raised.

Anyway, the change will bring incompatibility. We need to consider whether it is worth fixing at the cost of incompatibility issues.

Also available in: Atom PDF