0

When we try to redefine a constant, Ruby shows only a warning, but not any error. So one can always redefine a constant in Ruby?

Also a private method of a class can be invoked using the send method:

Const = 12
puts Const
#only an warning: already initialized constant Const
Const = 14
puts Const #Displays 14
class MyClass
private
    def priv
        puts 'In private method'
    end
end
obj = MyClass.new
#Error: private method `priv' called for #<MyClass:0x7f2cfda21738> (NoMethodError)
#obj.priv
#but this is fine!
obj.send(:priv)

Are there any rationale behind such designs in Ruby? Do not these violate the basic idea of constants and access specifiers respectively?

Is there any real, practical use of these designs? Some examples would be great if there are!

Note: I do see a lot of questions/discussions here regarding Ruby's constants and private methods, but I did not find anything related to the reason behind these.

Curious
  • 2,783
  • 3
  • 29
  • 45
  • I think it's simple. Ruby isn't Java. Access specifiers are guidelines, not rules set in stone. – Linuxios Mar 07 '13 at 14:28
  • @Linuxios Forget about Java or any other language and think about just the English words *'constant'* & *'private'*. Don't these design of Ruby violate the very interpretation of those 2 words? I have read that Ruby tries to be as much close as possible to spoken English! The popular Ruby book [Why's (poignant) guide to ruby](http://mislav.uniqpath.com/poignant-guide/book/) in fact opens with the idea that Ruby is close to how one thinks or reading in his own mind... – Curious Mar 07 '13 at 14:37
  • 1
    Ruby doesn't try to be a pedantic language that enforces rules, such as constants being locked in forever. If it were, the only constants we should be able to use would be those we find in scientific calculators. Instead, constants are things we don't want to change, but if we do accidentally, Ruby warns us so we can fix the code that caused the warning. As a programmer, it does me no good for Ruby to raise an exception and halt the code or silently ignore the reassignment without saying so, so its current behavior works nicely. – the Tin Man Mar 07 '13 at 15:12
  • @theTinMan:One can define scientific constant `pi = 3.142` & then re-define it `pi = 999999`! Warning raised by Ruby for it can easily be overlooked, more so if someone is not using the command line to run ruby, e.g. a code piece may be running from a web-page, thus letting hard to find bugs to slip in. Halting execution on a constant redefinition wouldn't make Ruby pedantic, I think! Ruby does have a few rules, e.g. class name must start with an upper case letter, but that does not make Ruby pedantic. Anyway I'm looking for the philosophy behind this, which does not seem to be there in Stack. – Curious Mar 07 '13 at 15:58

1 Answers1

3

As for send, the answer is rather simple: once you use reflection, all bets are off. Note that this is no different than in most other languages as well, you can also circumvent access restrictions in Java using reflection, for example.

And for constants, well, you do get a warning. You do get told that you are doing something you shouldn't. But Ruby is a language which trusts you that you know what you are doing. It won't get in your way. If you want to shoot yourself in the foot, you should be allowed to do that. Or, a more cynical way to look at it: there are so many evil things you can do in Ruby, redefining constants really doesn't matter that much.

Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653