Project

General

Profile

Actions

Feature #16644

closed

qualified const init (self::CONST1 = 1) should be allowed in methods

Added by bughit (bug hit) about 4 years ago. Updated about 4 years ago.

Status:
Rejected
Assignee:
-
Target version:
-
[ruby-core:97220]

Description

module Mod1
  def self.define_consts
    const_set(:CONST1, :CONST1)

    # this is actual const re-assignment but only a warning
    const_set(:CONST1, :CONST1)
    
    
    # this is const initialization but becomes an error
    # because it looks like it could be re-assignment
    # if actual const re-assignment is only a warning
    # why is a possible const re-assignment (which might not be one), an error
    self::CONST2 = :CONST2 unless const_defined?(:CONST2, false)
    
  end
  
  define_consts
end

Updated by jeremyevans0 (Jeremy Evans) about 4 years ago

  • Backport deleted (2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN)
  • Tracker changed from Bug to Misc
  • ruby -v deleted (ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-linux])

These are two different things. Ruby always warns for assigning to an existing constant, regardless of using const_set or CONST = .... It does not support using CONST = ... inside a method, though const_set is allowed. Similarly, you can use Class.new and Module.new to define classes and modules in method bodies, but you can't use the class or module keywords directly in method bodies.

This behavior exists at least back to 1.8, and probably before that. I'm fairly sure this is the expected behavior. If you would like the behavior changed, please submit a feature request.

I realize this does not directly answer the question in the issue subject. I'm switching this to the Misc tracker, since this is not a bug report.

Updated by bughit (bug hit) about 4 years ago

  • Tracker changed from Misc to Feature
  • Subject changed from why is potential dynamic constant assignment an error when actual dynamic constant assignment is only a warning to qualified const init (self::CONST1 = 1) should be allowed in methods

a qualified const init is so similar to meta-programming const_set that there's no reason to block it

module Mod1
end

  def define_consts(mod)
    
    # since this allowed
    mod.const_set(:CONST1, :CONST1) unless mod.const_defined?(:CONST1, false)
    
    # this should be too
    mod::CONST2 = :CONST2 unless mod.const_defined?(:CONST2, false)

  end

define_consts(Mod1)


Updated by matz (Yukihiro Matsumoto) about 4 years ago

Use const_set. I'd rather make all const re-assignment error if compatibility does not matter.

Matz.

Actions #4

Updated by matz (Yukihiro Matsumoto) about 4 years ago

  • Status changed from Open to Rejected

Updated by bughit (bug hit) about 4 years ago

I'd rather make all const re-assignment error

I don't disagree, actual const re-assignment, dynamically detected, probably should be an error. But then especially, there is no reason that a qualified const initialization (mod::CONST2 = :CONST2 unless mod.const_defined?(:CONST2, false)) should be an error. You would already be protected from const re-assignment, so why block what is simply a more direct syntax for initializing a const from a macro method?

Updated by Hanmac (Hans Mackowiak) about 4 years ago

@bughit (bug hit) i think you are looking for #const_missing instead?

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0