Overriding constants


#1

Hi there,
I’m trying to override the defaults for form_helper.
I can see in action_view/helpers/form_helper.rb:

class InstanceTag #:nodoc:
  include Helpers::TagHelper

  attr_reader :method_name, :object_name

  DEFAULT_FIELD_OPTIONS     = { "size" => 30 }.freeze unless 

const_defined?(:DEFAULT_FIELD_OPTIONS)
DEFAULT_RADIO_OPTIONS = { }.freeze unless
const_defined?(:DEFAULT_RADIO_OPTIONS)
DEFAULT_TEXT_AREA_OPTIONS = { “cols” => 40, “rows” => 20 }.freeze
unless const_defined?(:DEFAULT_TEXT_AREA_OPTIONS)
DEFAULT_DATE_OPTIONS = { :discard_type => true }.freeze unless
const_defined?(:DEFAULT_DATE_OPTIONS)

but if I add a simple declaration in my environment.rb, nothing seems to
happen (even after webserver reboot):

DEFAULT_FIELD_OPTIONS = { “size” => 30, “class” => “text” }
DEFAULT_TEXT_AREA_OPTIONS = { “wrap” => “virtual”, “rows” => 3, “cols”
=> 30, “class” => “input” }

do I need to wrap them in a module? I figured not, as they are
constants, and should be globally scoped, but I might be very wrong
about that…

This seems like it should be fairly straightforward, so I must be doing
something the wrong way.

thanks

dorian


#2

Maybe because of freeze? …
http://www.ruby-doc.org/core/classes/Object.html#M001425

View this message in context:
http://www.nabble.com/overriding-constants-t1722951.html#a4680880
Sent from the RubyOnRails Users forum at Nabble.com.


#3

hmmm…
I saw that as well, but wasn’t sure if environment.rb got loaded before
or after the all of the Action files.
If the helper file gets loaded first, then I can’t see a way to override
the defaults!


#4

oddly enough, I get what I want from script/console:

DEFAULT_FIELD_OPTIONS
=> {“size”=>30, “class”=>“text”}

DEFAULT_TEXT_AREA_OPTIONS
=> {“class”=>“input”, “wrap”=>“virtual”, “rows”=>3, “cols”=>30}

but it seems that const_defined() acts in a modular scope:

const_defined?(:DEFAULT_FIELD_OPTIONS)
NoMethodError: undefined method `const_defined?’ for
#Object:0x402e79c0
from (irb):1

so I tried:

ActionView.const_defined?(:DEFAULT_FIELD_OPTIONS)
=> false

but then putting this in my environment didn’t help either:
module ActionView
DEFAULT_FIELD_OPTIONS = { “size” => 30, “class” => “text” }
DEFAULT_TEXT_AREA_OPTIONS = { “wrap” => “virtual”, “rows” => 3, “cols”
=> 30, “class” => “input” }
end

I’m confused now.


#5

thanks for that,
I also had it working using:

class ActionView::Helpers::InstanceTag
DEFAULT_FIELD_OPTIONS = { “size” => 30, “class” => “text” }
DEFAULT_TEXT_AREA_OPTIONS = { “wrap” => “virtual”, “rows” => 3, “cols”
=> 30, “class” => “input” }
end

but whichever way I still get the warning:
./script/…/config/…/config/environment.rb:73: warning: already
initialized constant DEFAULT_FIELD_OPTIONS
./script/…/config/…/config/environment.rb:74: warning: already
initialized constant DEFAULT_TEXT_AREA_OPTIONS

it seems there’s no way to do it without getting at least a warning. I
find it odd that it even lets you do it at all because the
initialisation freezes hash, which I thought made it immutable (if
that’s the right word)

d


#6

Actually, you can override it with the right statements.

The constant is defined as:
http://caboo.se/doc/classes/ActionView/Helpers/InstanceTag.html
http://caboo.se/doc/classes/ActionView/Helpers/InstanceTag.html
DEFAULT_TEXT_AREA_OPTIONS = { “cols” => 40, “rows” => 20 }.freeze unless
const_defined?(:DEFAULT_TEXT_AREA_OPTIONS)

The key is the “unless const_defined?(…)”.
It says that the constant should be defined and frozen, UNLESS it is
aready
defined.

How do you define it before ActionView::Helpers::InstanceTag is
defined?.
Well, just define it at the beginning of environment.rb, however, since
neither ActionView, Helpers or InstanceTag is defined yet, we must
define
them fully with Module/Class…End blocks like this:

module ActionView
module Helpers
class InstanceTag
DEFAULT_TEXT_AREA_OPTIONS = { :cols => 60, :rows => 10 }
end
end
end

So, just add the code above at the top of your config/environment.rb,
and
you should be all set and warning-free. I hope this helps someone.

Gabriel Medina.
http://www.dottut.com/ http://www.dottut.com/


View this message in context:
http://www.nabble.com/overriding-constants-tf1722951.html#a13741535
Sent from the RubyOnRails Users mailing list archive at Nabble.com.


#7

dorian mcfarland wrote:

oddly enough, I get what I want from script/console:

DEFAULT_FIELD_OPTIONS
=> {“size”=>30, “class”=>“text”}

DEFAULT_TEXT_AREA_OPTIONS
=> {“class”=>“input”, “wrap”=>“virtual”, “rows”=>3, “cols”=>30}

but it seems that const_defined() acts in a modular scope:

const_defined?(:DEFAULT_FIELD_OPTIONS)
NoMethodError: undefined method `const_defined?’ for
#Object:0x402e79c0
from (irb):1

so I tried:

ActionView.const_defined?(:DEFAULT_FIELD_OPTIONS)
=> false

but then putting this in my environment didn’t help either:
module ActionView
DEFAULT_FIELD_OPTIONS = { “size” => 30, “class” => “text” }
DEFAULT_TEXT_AREA_OPTIONS = { “wrap” => “virtual”, “rows” => 3, “cols”
=> 30, “class” => “input” }
end

I’m confused now.

Hi Dorian,

You are close, but you got the InstanceTag package wrong. Try this under
environment.rb

ActionView::Helpers::InstanceTag::DEFAULT_FIELD_OPTIONS = {…custom
values…}