Bug #15928

Constant declaration does not conform to JIS 3017:2013

Added by yugui (Yuki Sonoda) 10 months ago. Updated 10 months 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) 10 months 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) 10 months 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