# Rake, Hoe, Meta-Programming, and Warnings (oh my!)

**URL:** <https://www.ruby-forum.com/t/rake-hoe-meta-programming-and-warnings-oh-my/82336>\
**Category:** Ruby\
**Created:** [January 19, 2007, 4:29pm UTC](https://www.ruby-forum.com/t/rake-hoe-meta-programming-and-warnings-oh-my/82336 "2007-01-19T16:29:23Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![timperrett](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/c5a1d2/32.png) [@timperrett](https://www.ruby-forum.com/u/timperrett)\
**Post date:** [January 19, 2007, 4:29pm UTC](https://www.ruby-forum.com/t/rake-hoe-meta-programming-and-warnings-oh-my/82336/1 "2007-01-19T16:29:23Z")

</div>

Is there a way to disable specific warnings from within a Ruby program  
(not from the command line)?

The warnings are coming from some meta-programming code that is  
redefining instance methods on the fly based on user input. So maybe a  
better question would be, is there a way to redefine methods without  
causing Ruby to spew out a warning each time the method is redefined.

This is the result of using Hoe (thanks Ryan, Eric, and other sun  
deprived Rubyists) to run my unit tests. Hoe adds the -w flag to the  
Ruby interpreter when it runs tests. This is a good thing as it found  
several minor flaws in my code. But redefining methods is at the heart  
of what I’m trying to do.

Example:

class Pattern  
def self.create\_date\_format\_methods( pf )  
module\_eval \<\<-CODE  
def pf.format\_date  
Time.now.strftime “#{pf.date\_pattern}”  
end  
CODE  
end  
end

When running unit tests with the -w flag …

(eval):1: warning: redefine format\_date

Any thoughts on how to suppress the warning and/or change my  
meta-programming so the warning does not show up?

Blessings,  
TwP

---

<div class="post-metadata">

**Author:** ![timperrett](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/c5a1d2/32.png) [@timperrett](https://www.ruby-forum.com/u/timperrett)\
**Post date:** [January 19, 2007, 4:29pm UTC](https://www.ruby-forum.com/t/rake-hoe-meta-programming-and-warnings-oh-my/82336/2 "2007-01-19T16:29:34Z")

</div>

Tim P. wrote:

> Is there a way to disable specific warnings from within a Ruby program  
> (not from the command line)?
> 
> The warnings are coming from some meta-programming code that is  
> redefining instance methods on the fly based on user input. So maybe a  
> better question would be, is there a way to redefine methods without  
> causing Ruby to spew out a warning each time the method is redefined.

Sure - redefine Kernel#warn. 😉

Seriously, I think what we need are structured warnings. I brought  
this up way back in 2002: [http://tinyurl.com/yfko6z](http://tinyurl.com/yfko6z)

I’m certainly not the first to think of it (Perl lets you disable  
specific kinds of warnings, it’s been brought up on IRC several times  
over the years), but some sort of structured warning that programmers  
could specifically raise and/or ignore is something I’ve wanted for a  
long time.

I would think it would just be a matter of copying exception.c, ripping  
out the longjmp/exit parts of it, defining a warning hierarchy, and  
adding a Warning.ignore class method. Of course, it probably isn’t  
that simple.

Any, I imagine instead of doing this within your code:

warn, “redefinition of constant FOO”

Internally, you would do this:

raise RedefinedWarning, “redefinition of constant FOO”

And then, a programmer could do this:

RedefinedWarning.ignore # ignore all redefintion warnings

And, I think Sean originally suggested allowing a block syntax, so you  
could temporarily ignore warnings:

RedefinedWarning.ignore do

# Ignore redefinition warnings within this block only

end

Back to your question, though, I suppose we would have add a  
Warning.disable in order to prevent the warning from ever being  
generated in the first place:

RedefinedWarning.disable do  
def some\_method  
# Pretend you didn’t notice that I’ve redefined this method  
end  
end

Whether that’s good practice or not, I leave to the viewing audience.

Probably a much longer answer than you wanted, but there you go.

Regards,

Dan

---

<div class="post-metadata">

**Author:** ![timperrett](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/c5a1d2/32.png) [@timperrett](https://www.ruby-forum.com/u/timperrett)\
**Post date:** [January 19, 2007, 4:30pm UTC](https://www.ruby-forum.com/t/rake-hoe-meta-programming-and-warnings-oh-my/82336/3 "2007-01-19T16:30:50Z")

</div>

Tim P. wrote:

> class Pattern  
> def self.create\_date\_format\_methods( pf )  
> old, $VERBOSE = $VERBOSE, nil  
> module\_eval \<\<-CODE  
> def pf.format\_date  
> Time.now.strftime “#{pf.date\_pattern}”  
> end  
> CODE  
> ensure  
> $VERBOSE = old

---

<div class="post-metadata">

**Author:** ![timperrett](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/c5a1d2/32.png) [@timperrett](https://www.ruby-forum.com/u/timperrett)\
**Post date:** [January 19, 2007, 4:29pm UTC](https://www.ruby-forum.com/t/rake-hoe-meta-programming-and-warnings-oh-my/82336/4 "2007-01-19T16:29:49Z")

</div>

On 1/12/07, Daniel B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> out the longjmp/exit parts of it, defining a warning hierarchy, and
> 
> Whether that’s good practice or not, I leave to the viewing audience.
> 
> Probably a much longer answer than you wanted, but there you go.

Long answers are usually the most educational ones (or the most  
inflammatory).

I can understand why this would cause a warning – if someone  
inadvertently redefined a method, this would be a nice check. However,  
this is my desired behavior .

As Florian mentioned, redefining $VERBOSE will suppress the warnings.  
It “feels” a little kludgy to me, though.

Hmmm … maybe Matz doesn’t want the performance hit of having to  
perform a warning table lookup for each line of code parsed. That  
would be one good reason to disallow fine grained warning control.

How’s the snow down in your neck of the woods?

Blessings,  
TwP

---

<div class="post-metadata">

**Author:** ![timperrett](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/c5a1d2/32.png) [@timperrett](https://www.ruby-forum.com/u/timperrett)\
**Post date:** [January 19, 2007, 4:31pm UTC](https://www.ruby-forum.com/t/rake-hoe-meta-programming-and-warnings-oh-my/82336/5 "2007-01-19T16:31:26Z")

</div>

On Jan 12, 2007, at 11:24 AM, Tim P. wrote:

> The warnings are coming from some meta-programming code that is  
> redefining instance methods on the fly based on user input. So maybe a  
> better question would be, is there a way to redefine methods without  
> causing Ruby to spew out a warning each time the method is redefined.

Sure. Watch:

#!/usr/bin/env ruby -w

class Test  
def override  
“original”  
end  
end

Test.new.override # =\> “original”

class Test  
def override # !\> method redefined; discarding old override  
“warning”  
end  
end

Test.new.override # =\> “warning”

class Test  
undef :override  
def override  
“no warning”  
end  
end

Test.new.override # =\> “no warning”

class Test  
alias\_method :old\_override, :override  
def override  
“alias avoids warning too”  
end  
end

Test.new.override # =\> “alias avoids warning too”

**END**

Hope that helps.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![timperrett](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/c5a1d2/32.png) [@timperrett](https://www.ruby-forum.com/u/timperrett)\
**Post date:** [January 19, 2007, 4:30pm UTC](https://www.ruby-forum.com/t/rake-hoe-meta-programming-and-warnings-oh-my/82336/6 "2007-01-19T16:30:01Z")

</div>

Tim P. wrote:

> Ruby interpreter when it runs tests. This is a good thing as it found  
> Time.now.strftime “#{pf.date\_pattern}”
> 
> Any thoughts on how to suppress the warning and/or change my  
> meta-programming so the warning does not show up?
> 
> Blessings,  
> TwP

I understand that this isn’t identical to what you’re doing, but it  
demonstrates how define\_method won’t cause a warning.

class Foo  
define\_method(:bar) do  
puts “bar”  
end  
def cat  
puts “cat”  
end  
end

Foo.new.bar  
Foo.new.cat

class Foo  
define\_method(:bar) do  
puts “bar2”  
end  
def cat  
puts “cat2”  
end  
end

Foo.new.bar  
Foo.new.cat

> ruby -w foo.rb  
> bar  
> cat  
> foo.rb:17: warning: method redefined; discarding old cat  
> bar2  
> cat2

---

<div class="post-metadata">

**Author:** ![timperrett](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/c5a1d2/32.png) [@timperrett](https://www.ruby-forum.com/u/timperrett)\
**Post date:** [January 19, 2007, 4:32pm UTC](https://www.ruby-forum.com/t/rake-hoe-meta-programming-and-warnings-oh-my/82336/7 "2007-01-19T16:32:02Z")

</div>

On 1/12/07, James Edward G. II [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> "warning"
> 
> ```
> 
> end  
> Test.new.override # =\> “alias avoids warning too”
> 
> **END**
> 
> Hope that helps.

Hey James! That did the trick.

I could have sworn that I tried undef before, but in my current sleep  
deprived state I’m not too sure about it. Hmmm … I most likely did  
try undef, but it chucked an exception at me when I tried to undef a  
non-existent method.

Now using undef along with method\_defined?

All is well 🙂

Blessings,  
TwP

---

<div class="post-metadata">

**Author:** ![timperrett](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/c5a1d2/32.png) [@timperrett](https://www.ruby-forum.com/u/timperrett)\
**Post date:** [January 19, 2007, 4:31pm UTC](https://www.ruby-forum.com/t/rake-hoe-meta-programming-and-warnings-oh-my/82336/8 "2007-01-19T16:31:59Z")

</div>

On 1/12/07, Mike H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> end  
> end  
> cat2

There is going to be a performance hit with define\_method. Since the  
method body is a block, each time it is called a Binding to the  
instance will have to be created in which the block will be run.

$ cat a.rb

require ‘benchmark’

class Object  
def method() end  
define\_method(:method1) {}  
end

this\_many = 1\_000\_000  
::Benchmark.bm(10) do |bm|  
bm.report(‘method :’) {this\_many.times {method()}}  
bm.report(‘method1 :’) {this\_many.times {method1()}}  
end

$ ruby a.rb  
user system total real  
method : 0.400000 0.000000 0.400000 ( 0.400000)  
method1 : 1.272000 0.000000 1.272000 ( 1.282000)

It is a factor of 3 slower ☹

Blessings,  
TwP
