Proposal: debug keyword


(Simon Strandgaard) #1

A debug keyword which enables debug-output for a specific method.
I have found its useful when there is many testcases which fails
at the same time, letting me faster identify where the problem is.

I think this would be a good idea to have distributed with Ruby?
I am thinking of submitting an RCR, should I do this?

Its syntax is

debug :method [, :method]*

What it does is to enable the global flag $debug.

If we type ‘debug :test_a1’, then we get the following output

ruby example.rb
Loaded suite TestA
Started
test_a1(TestA): before #test_a1
A#compute, begin
A#dostuff, begin
A#dostuff, end
A#compute, end
after #test_a1

Finished in 0.002609 seconds.

1 tests, 1 assertions, 0 failures, 0 errors

However if we doesn’t type it, then we get our normal output.

ruby example.rb
Loaded suite TestA
Started
test_a1(TestA): .

Finished in 0.001572 seconds.

1 tests, 1 assertions, 0 failures, 0 errors

Its a bit hackish, but it works.

expand -t2 debug_keyword.rb
BEGIN {
$debug = false
}

purpose:

make it easy to enable/disable debugging

···

if $debug == nil then output are disabled

if $debug != nil then output are enabled

module Debuggable
def printx(*args)
if $debug
super(*args)
end
end
def puts(*args)
if $debug
super(*args)
end
end
def p(*args)
if $debug
super(*args)
end
end
def print(*args)
if $debug
super(*args)
end
end
end

purpose:

enable $debug flag inside a method

class Test

include Debuggable

def test_x; p 42; end

debug :test_x

end

Test.new.test_x #-> (before ‘test_x’) 42 (after ‘test_x’)

class Module

enable the global debug flag for just a single method

def debug(*args)
debug_methods = private_instance_methods(true)
args.each do |symbol|
name = symbol.id2name
org = “debug”+name
if debug_methods.include?(org)
$stderr.puts "ERROR: already debugging method: #{name}"
next
end
begin
meth = instance_method(symbol)
rescue => e
$stderr.puts "ERROR: symbol2method failure, " + e.inspect
next
end
arguments = (meth.arity != 0) ? “(*a,&b)” : "(&b)"
alias_method org, name
module_eval %{
def #{name}#{arguments}
$stdout.puts(“before ##{name}”)
debug, $debug = $debug, true
result = #{org}#{arguments}
$stdout.puts(“after ##{name}”)
result
ensure
$debug = debug
end
private :#{org}
}
end
end
end

expand -t2 example.rb
require 'debug_keyword’
class A
include Debuggable
def dostuff
puts "A#dostuff, begin"
puts "A#dostuff, end"
end
def compute
puts "A#compute, begin"
dostuff
puts "A#compute, end"
42
end
end

require 'test/unit’
class TestA < Test::Unit::TestCase
def test_a1
assert_equal(42, A.new.compute)
end
debug :test_a1 # enable/disable debugging
end

require 'test/unit/ui/console/testrunner’
Test::Unit::UI::Console::TestRunner.run(TestA, Test::Unit::UI::VERBOSE)


Simon Strandgaard

BTW: Thanks Nobu, Decoux for helping working the debug keyword :wink:


(Robert) #2

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.02.25.12.16.49.825996@adslhome.dk

A debug keyword which enables debug-output for a specific method.
I have found its useful when there is many testcases which fails
at the same time, letting me faster identify where the problem is.

I think this would be a good idea to have distributed with Ruby?
I am thinking of submitting an RCR, should I do this?

Its syntax is

debug :method [, :method]*

What it does is to enable the global flag $debug.

More precisely it switches all output on or off in a method. And that’s
what I don’t like about it: in your example class A behavior of “puts”,
“print” etc. changes depending on the $debug flag. That’s IMHO not
compliant with POLS. I’d prefer to have specialized methods for debug
printing.

Kind regards

robert

(Simon Strandgaard) #3

[snip]

I think this would be a good idea to have distributed with Ruby?
I am thinking of submitting an RCR, should I do this?

Question still stands, should I make an RCR out of it?

Consideration if the name ‘debug’ is ok?

Temporary enabling a global flag is more general,
perhaps its better to make a temporary-set method

temp_set $global_variable, :method

Instead of naming it ‘debug’, then maybe name it

temp_set_debug :method

What should be in the RCR?
the ‘temp_set’ thing or the ‘debug’ keyword thing?

Sorry for rambling… needs more input :wink:

···

On Wed, 25 Feb 2004 13:16:50 +0100, Simon Strandgaard wrote:


Simon Strandgaard


(Simon Strandgaard) #4

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag

Its syntax is

debug :method [, :method]*

What it does is to enable the global flag $debug.

More precisely it switches all output on or off in a method. And that’s
what I don’t like about it: in your example class A behavior of “puts”,
“print” etc. changes depending on the $debug flag. That’s IMHO not
compliant with POLS.

Agree it isn’t POLS, but debugging is sometimes tuff.

I never remove print statements… because I one day might need that
information. Then a debug keyword + Debuggable module is practical.
I have attached a debug output from a testcase (my regexp project).

I have used logfiles in the past… but in conjunction with
unittesting they seems to be not needed.

I’d prefer to have specialized methods for debug printing.

Please enlighten me. How do you debug ?

It would be nice to identify a good model for advanced debugging with
Test::Unit.

···

On Wed, 25 Feb 2004 14:26:36 +0100, Robert Klemme wrote:


Simon Strandgaard

Loaded suite TestScanner
Started
test_verbose_alt_rep1(TestScanner): before #test_verbose_alt_rep1
regexp="(foob|fo|o)*bar"
±Sequence
±Repeat greedy{0,-1}

±Group register=1
±Alternation
±Sequence
> ±Literal “f”
> ±Literal “o”
> ±Literal “o”
> ±Literal "b"
±Sequence
> ±Literal “f”
> ±Literal "o"
±Literal "o"
±Literal "b"
±Literal "a"
±Literal "r"
input=“xfoobarx”


execute at position 0
repeat 0
visitor#set_state from active into inactive
match “b” at position 0
path end = expected “b” but got "x"
check_integrity history.size=1
index-stack=[0]
integrity “bar” (line 0)

next_path zero. found=false lazy=false state=active index=0 has_match=false
clear history
replace zero with one
visitor#set_state from inactive into active
visitor#set_memento
group_open register=1
alternation 0
match “f” at position 0
path end = expected “f” but got "x"
check_integrity history.size=2
index-stack=[1, 0]
integrity “foob bar” (line 1)

next_path alternation. index=0->1
visitor#set_memento
match “f” at position 0
path end = expected “f” but got "x"
check_integrity history.size=2
index-stack=[1, 1]
integrity “fo bar” (line 2)

next_path alternation. index=1->2
visitor#set_memento
match “o” at position 0
path end = expected “o” but got "x"
check_integrity history.size=2
index-stack=[1, 2]
integrity “o bar” (line 3)

next_path alternation. index=2->3, exhausted
skip, path end = exhausted
next_path one. found=false lazy=false state=active index=0 has_match=false
clear history
skip, path end = is done
execute at position 1
repeat 0
visitor#set_state from active into inactive
match “b” at position 1
path end = expected “b” but got "f"
check_integrity history.size=1
index-stack=[0]
integrity “bar” (line 4)

next_path zero. found=false lazy=false state=active index=0 has_match=false
clear history
replace zero with one
visitor#set_state from inactive into active
visitor#set_memento
group_open register=1
alternation 0
match “f” at position 1
match “o” at position 2
match “o” at position 3
match “b” at position 4
group_close register=1
visitor#set_state from active into inactive
one-end
match “b” at position 5
path end = expected “b” but got "a"
check_integrity history.size=3
index-stack=[1, 0]
integrity “foob bar” (line 5)

next_path zero. found=false lazy=false state=active index=1 has_match=false
clear history
replace zero with one
visitor#set_state from inactive into active
visitor#set_memento
group_open register=1
alternation 0
match “f” at position 5
path end = expected “f” but got "a"
check_integrity history.size=4
index-stack=[2, 0, 0]
integrity “foob foob bar” (line 6)

next_path alternation. index=0->1
visitor#set_memento
match “f” at position 5
path end = expected “f” but got "a"
check_integrity history.size=4
index-stack=[2, 0, 1]
integrity “foob fo bar” (line 7)

next_path alternation. index=1->2
visitor#set_memento
match “o” at position 5
path end = expected “o” but got "a"
check_integrity history.size=4
index-stack=[2, 0, 2]
integrity “foob o bar” (line 8)

next_path alternation. index=2->3, exhausted
skip, path end = exhausted
next_path one. found=false lazy=false state=active index=1 has_match=false
clear history
skip, path end = is done
next_path alternation. index=0->1
visitor#set_memento
match “f” at position 1
match “o” at position 2
group_close register=1
visitor#set_state from active into inactive
one-end
match “b” at position 3
path end = expected “b” but got "o"
check_integrity history.size=3
index-stack=[1, 1]
integrity “fo bar” (line 9)

next_path zero. found=false lazy=false state=active index=1 has_match=false
clear history
replace zero with one
visitor#set_state from inactive into active
visitor#set_memento
group_open register=1
alternation 0
match “f” at position 3
path end = expected “f” but got "o"
check_integrity history.size=4
index-stack=[2, 1, 0]
integrity “fo foob bar” (line 10)

next_path alternation. index=0->1
visitor#set_memento
match “f” at position 3
path end = expected “f” but got "o"
check_integrity history.size=4
index-stack=[2, 1, 1]
integrity “fo fo bar” (line 11)

next_path alternation. index=1->2
visitor#set_memento
match “o” at position 3
group_close register=1
visitor#set_state from active into inactive
one-end
match “b” at position 4
match “a” at position 5
match “r” at position 6
last
path end = reached last node
check_integrity history.size=5
index-stack=[2, 1, 2]
integrity “fo o bar” (line 12)

next_path zero. found=true lazy=false state=active index=2 has_match=false
remember zero and clear
replace zero with one
visitor#set_state from inactive into active
visitor#set_memento
group_open register=1
alternation 0
match “f” at position 4
path end = expected “f” but got "b"
check_integrity history.size=6
index-stack=[3, 1, 2, 0]
integrity “fo o foob bar” (line 13)

next_path alternation. index=0->1
visitor#set_memento
match “f” at position 4
path end = expected “f” but got "b"
check_integrity history.size=6
index-stack=[3, 1, 2, 1]
integrity “fo o fo bar” (line 14)

next_path alternation. index=1->2
visitor#set_memento
match “o” at position 4
path end = expected “o” but got "b"
check_integrity history.size=6
index-stack=[3, 1, 2, 2]
integrity “fo o o bar” (line 15)

next_path alternation. index=2->3, exhausted
skip, path end = exhausted
next_path one. found=false lazy=false state=active index=2 has_match=true
clear history
install match
visitor#set_memento
skip, path end = is done
next_path alternation. index=2->3, found
skip, path end = found
next_path one. found=true lazy=false state=active index=1 has_match=true
remember one and clear
install match
visitor#set_memento
skip, path end = is done
next_path alternation. index=1->2, found
skip, path end = found
next_path one. found=true lazy=false state=active index=0 has_match=true
remember one and clear
install match
visitor#set_memento
----- BEGIN before activate -----
content of history stack
0: ONE_0 quantifier_id=0
1: ALT_1
2: ONE_1 quantifier_id=0
3: ALT_2
4: ZERO_2 quantifier_id=0
quantifier information
0: active found=no
----- END before activate -----
activate_next
found zero/one
activate_inactive
----- BEGIN after activate -----
content of history stack
0: ONE_0 quantifier_id=0
1: ALT_1
2: ONE_1 quantifier_id=0
3: ALT_2
4: ZERO_2 quantifier_id=0
quantifier information
0: done found=no
----- END after activate -----
skip, path end = is done
next_path zero. found=true lazy=false state=done index=2 has_match=false
skip, path end = done
next_path alternation. index=2->3, found
skip, path end = found
next_path one. found=true lazy=false state=done index=1 has_match=false
skip, path end = done
next_path alternation. index=1->2, found
skip, path end = found
next_path one. found=true lazy=false state=done index=0 has_match=false
skip, path end = done

result=[“foobar”, “o”]
after #test_verbose_alt_rep1

Finished in 0.026799 seconds.

1 tests, 1 assertions, 0 failures, 0 errors


(Robert) #5

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.02.26.13.08.27.945491@adslhome.dk

[snip]

I think this would be a good idea to have distributed with Ruby?
I am thinking of submitting an RCR, should I do this?

Question still stands, should I make an RCR out of it?

Consideration if the name ‘debug’ is ok?

When switching debugging for certain methods “debug_method” is more
appropriate IMHO. “debug” implies some global thingy. My 0.02 EUR…

Temporary enabling a global flag is more general,
perhaps its better to make a temporary-set method

temp_set $global_variable, :method

Instead of naming it ‘debug’, then maybe name it

temp_set_debug :method

What should be in the RCR?
the ‘temp_set’ thing or the ‘debug’ keyword thing?

Sorry for rambling… needs more input :wink:

Hm… Just as food for thought: how about some more aspect oriented
solution, i.e., debug aspects to switch on and off (see attachment).

Regards

robert

debug-2.rb (1.03 KB)

···

On Wed, 25 Feb 2004 13:16:50 +0100, Simon Strandgaard wrote:


(Simon Strandgaard) #6

no replies… I have submitted an RCR.
http://rcrchive.net/rcr/RCR/RCR224

BTW: Please vote :wink:

···

On Thu, 26 Feb 2004 14:08:28 +0100, Simon Strandgaard wrote:

On Wed, 25 Feb 2004 13:16:50 +0100, Simon Strandgaard wrote:
[snip]

I think this would be a good idea to have distributed with Ruby?
I am thinking of submitting an RCR, should I do this?

Question still stands, should I make an RCR out of it?


Simon Strandgaard


(Robert) #7

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.02.25.13.47.23.98604@adslhome.dk

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag

Its syntax is

debug :method [, :method]*

What it does is to enable the global flag $debug.

More precisely it switches all output on or off in a method. And
that’s

what I don’t like about it: in your example class A behavior of
"puts",

“print” etc. changes depending on the $debug flag. That’s IMHO not
compliant with POLS.

Agree it isn’t POLS, but debugging is sometimes tuff.

Taff? Well, yes it is.

I never remove print statements… because I one day might need that
information. Then a debug keyword + Debuggable module is practical.
I have attached a debug output from a testcase (my regexp project).

I have used logfiles in the past… but in conjunction with
unittesting they seems to be not needed.

I’d prefer to have specialized methods for debug printing.

Please enlighten me. How do you debug ?

? Sorry if I wasn’t clear enough. The thing I don’t like is the naming
of the methods used for debug printing. I mean, rather use different
names than “puts”, “print” etc. in order to be able to have regular output
as well as debug output. Also it helps in identifying lines that can be
taken out once the code is ok. (Ok, you don’t take them out so this
argument doesn’t count for you - but other IMHO.)

Is there a reason why your debug output methods need to override methods
defined in Kernel?

It would be nice to identify a good model for advanced debugging with
Test::Unit.

Yeah.

robert
···

On Wed, 25 Feb 2004 14:26:36 +0100, Robert Klemme wrote:


(Steve Tuckner) #8

Simon Strandgaard wrote:

I’d prefer to have specialized methods for debug printing.

Please enlighten me. How do you debug ?

It would be nice to identify a good model for advanced debugging with
Test::Unit.

I too am interested in how others debug their unit tests (or code in
general). I am preparing to release my vrtools library an am removing my
trace statements in them because it seems like an unnecessary dependency
(perhaps just my way of working). Below is my trace module that I use
all the time. I once tried log4r but didn’t like it because it didn’t
seem easy to turn on and off debugging when I needed it to. My output
includes the code and line number which my editor links up when the unit
test is done running. Also it includes a time stamp to help with any
timing related issues. I can include and exclude debug in various ways
and direct output to a file. It all works pretty well for me (not
perfectly – for example some things could be named better).

So my requirements for a simple tracing/debugging system are for me:

  1. Trace output should include file/line number plus time stamp
  2. Need to be able to turn it on and off at run time
  3. Need to be able to filter which debug statements come out by debug
    level, function, file, possibly other considerations
  4. Need to be able to redirect output to a file

What are others requirements?

Maybe log4r provides all these capabilities and if so enlighten me please.

Steve Tuckner

----------------- Examples of use ---------------------------
require “my/mytrace” # to use my tracing this
creates a global $TRACE of class Tracer

$TRACE.set_level 5 # sets the level under which
traces will appear
$TRACE.exclude_files(“foo.rb”) # this excludes any traces in
foo.rb from coming out
$TRACE.include_files(“bar.rb”) # this overrides exculsions to
only allow traces from included files
$TRACE.exclude_functions(:foo, :bar) # this excludes any traces from
coming out from these functions (no matter the class)
$TRACE.set_output(“out.txt”) # write each statement to the
output file and close it after every trace (this is not as bad as it
sounds and if the program dies you definitiely get all the trace)

$TRACE.debug 5, “this is a trace” # this is the basic trace
statement with level 5

----------------- Example of program and output ---------------------------
--------------------------- tracetest.rb ----------
require “my/mytrace”

def foo
$TRACE.debug 5, "I am in foo"
puts "not a debug statement"
end

$TRACE.set_level 5
foo
$TRACE.set_level 0
foo

-------------------------- output -----------------
[tracetest.rb:4 ] [02/25/04 08:47:51] I am in foo
not a debug statement
not a debug statement

···

----------------- Trace code

class Tracer
def initialize
@trace_level = 0
@file = nil
@width = 25
@excluded_functions = []
@excluded_files = []
@output_to_screen_always = false
end

def set_width(width)
    @width = width
end

def trace(str, level=1)
    #old_dollar_equal = $=
    #$= = false
   
    if @trace_level >= level then
        m = /([\w_]+\.rb):(\d+):in `(.*)'/.match(caller[1])
        if m then
            filename = m[1]
            line = m[2].to_i
            function = m[3]

            t = Time.current.strftime("%m/%d/%y %H:%M:%S")
            str = sprintf "[%-#{@width}s] [%s] %s", 

“#{m[1]}:#{m[2]}”, t, str

            if @included_files then
                return unless @included_files.include?(filename)
            else
                if @excluded_functions.include?(function) then
                    return
                end

                if @excluded_files.include?(filename) then
                    return
                end
            end
        end               

        if @filename then
            File.open(@filename, "a") {|f| f.print str, "\n"}
        end
       
        if !@filename || @output_to_screen_always then               
            puts str
            $stdout.flush
        end
    end
ensure
    #$= = old_dollar_equal
end

def debug(level, str)
    trace(str, level)
end

def set_level(level)
    @trace_level = level
end

def set_level_include(level, included_files)
    @trace_level = level
    @included_files = included_files
end

def set_output(filename)
    @filename = filename
    File.open(@filename, "w") {}
end

def set_output_io(io)
    @io = io
end

def set_output_to_screen_always
    @output_to_screen_always = true
end
def exclude_functions(functions)
    @excluded_functions += functions
end

def exclude_files(filenames)
    @excluded_files += filenames
end

end

define the $TRACE variable if not already defined

if !$TRACE then
$TRACE = Tracer.new
end


(Simon Strandgaard) #9

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.02.25.13.47.23.98604@adslhome.dk

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag

Its syntax is

debug :method [, :method]*

What it does is to enable the global flag $debug.

More precisely it switches all output on or off in a method. And
that’s

what I don’t like about it: in your example class A behavior of
"puts",

“print” etc. changes depending on the $debug flag. That’s IMHO not
compliant with POLS.

Agree it isn’t POLS, but debugging is sometimes tuff.

Taff? Well, yes it is.

First I tried with ‘toff’ but it looked wrong :wink:

I never remove print statements… because I one day might need that
information. Then a debug keyword + Debuggable module is practical.
I have attached a debug output from a testcase (my regexp project).

I have used logfiles in the past… but in conjunction with
unittesting they seems to be not needed.

I’d prefer to have specialized methods for debug printing.

Please enlighten me. How do you debug ?

? Sorry if I wasn’t clear enough. The thing I don’t like is the naming
of the methods used for debug printing. I mean, rather use different
names than “puts”, “print” etc. in order to be able to have regular output
as well as debug output. Also it helps in identifying lines that can be
taken out once the code is ok. (Ok, you don’t take them out so this
argument doesn’t count for you - but other IMHO.)

Understandable… using puts, print has drawbacks. Good suggestion, I
think I will replace them with something else.

Any ideas for a good name?

debug replacement puts -> #debug_puts, #dputs
debug replacement p -> #debug_p, #dp

maybe just turn the ‘p’ in ‘puts’ upsidedown, so it becomes a ‘d’ => duts?

Is there a reason why your debug output methods need to override methods
defined in Kernel?

do you mean ‘class Module’?

Yes there is a good reason… by having it here, allows me to use
the debug keyword inside modules. Like this:

module TodoVerbose
	include MatchVerbose
	debug :test_verbose_alt_rep1
	#undef test_verbose_alt_rep1
	#debug :test_verbose_alt_rep2
	undef test_verbose_alt_rep2
	#debug :test_verbose_repeat1
	undef test_verbose_repeat1
	#debug :test_verbose_repeat2
	undef test_verbose_repeat2
	debug :test_verbose_repeat3
	undef test_verbose_repeat3
end

If the ‘debug’ keyword was defined in class Object, then
above wouldn’t be possible.

It would be nice to identify a good model for advanced debugging with
Test::Unit.

Yeah.

Agree :wink:

···

On Wed, 25 Feb 2004 15:09:03 +0100, Robert Klemme wrote:

On Wed, 25 Feb 2004 14:26:36 +0100, Robert Klemme wrote:


Simon Strandgaard


(Robert) #10

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.02.25.14.22.29.534174@adslhome.dk

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.02.25.13.47.23.98604@adslhome.dk

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag

Its syntax is

debug :method [, :method]*

What it does is to enable the global flag $debug.

More precisely it switches all output on or off in a method. And
that’s

what I don’t like about it: in your example class A behavior of
"puts",

“print” etc. changes depending on the $debug flag. That’s IMHO not
compliant with POLS.

Agree it isn’t POLS, but debugging is sometimes tuff.

Taff? Well, yes it is.

First I tried with ‘toff’ but it looked wrong :wink:

Actually, “tough” looks even better. :-))

I never remove print statements… because I one day might need that
information. Then a debug keyword + Debuggable module is practical.
I have attached a debug output from a testcase (my regexp project).

I have used logfiles in the past… but in conjunction with
unittesting they seems to be not needed.

I’d prefer to have specialized methods for debug printing.

Please enlighten me. How do you debug ?

? Sorry if I wasn’t clear enough. The thing I don’t like is the
naming

of the methods used for debug printing. I mean, rather use different
names than “puts”, “print” etc. in order to be able to have regular
output

as well as debug output. Also it helps in identifying lines that can
be

taken out once the code is ok. (Ok, you don’t take them out so this
argument doesn’t count for you - but other IMHO.)

Understandable… using puts, print has drawbacks. Good suggestion, I
think I will replace them with something else.

Any ideas for a good name?

debug replacement puts -> #debug_puts, #dputs
debug replacement p -> #debug_p, #dp

Hm… I’d go for “d_puts” which is immediately distinguished from "puts"
but is not so much typing overhead as the more verbose “debug_puts”.

maybe just turn the ‘p’ in ‘puts’ upsidedown, so it becomes a ‘d’ =>
duts?

http://www.best-lyrics-zone.net/Upside_Down_Lyrics.html
:slight_smile:

Is there a reason why your debug output methods need to override
methods

defined in Kernel?

do you mean ‘class Module’?

Nope, that question was referring to the naming of the methods which in
turn lead to shadowing the original methods “puts” etc. (see above). But
I think we have sorted that out by now. :slight_smile:

Yes there is a good reason… by having it here, allows me to use
the debug keyword inside modules. Like this:

Of course.

It would be nice to identify a good model for advanced debugging with
Test::Unit.

Yeah.

Agree :wink:

You agree to yourself? That’s a good sign - at least you don’t seem to
suffer from MPD* (at leat not at the moment. :-))

Cheers

robert
···

On Wed, 25 Feb 2004 15:09:03 +0100, Robert Klemme wrote:

On Wed, 25 Feb 2004 14:26:36 +0100, Robert Klemme wrote:


(Simon Strandgaard) #11

BTW: I had to change my taste of music so it reflect the language I am using

diamonds are forever
lucy in the sky with diamonds
diamonds are a girls best friend

···

On Wed, 25 Feb 2004 15:38:53 +0100, Robert Klemme wrote:

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag

Any ideas for a good name?

debug replacement puts -> #debug_puts, #dputs
debug replacement p -> #debug_p, #dp

Hm… I’d go for “d_puts” which is immediately distinguished from "puts"
but is not so much typing overhead as the more verbose “debug_puts”.

maybe just turn the ‘p’ in ‘puts’ upsidedown, so it becomes a ‘d’ =>
duts?

http://www.best-lyrics-zone.net/Upside_Down_Lyrics.html
:slight_smile:


Simon Strandgaard


(Charles Comstock) #12

Simon Strandgaard wrote:

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag

Any ideas for a good name?

debug replacement puts -> #debug_puts, #dputs
debug replacement p -> #debug_p, #dp

Hm… I’d go for “d_puts” which is immediately distinguished from "puts"
but is not so much typing overhead as the more verbose “debug_puts”.

maybe just turn the ‘p’ in ‘puts’ upsidedown, so it becomes a ‘d’ =>

duts?

http://www.best-lyrics-zone.net/Upside_Down_Lyrics.html
:slight_smile:

BTW: I had to change my taste of music so it reflect the language I am using

diamonds are forever
lucy in the sky with diamonds
diamonds are a girls best friend


Simon Strandgaard

It would be nice if we had macros for the debug stuff, so the code would
never even be seen when you didn’t do debug code. For instance if
instead for debug output you had a debug block, which was evaled and
added to the code on the first pass, so it would execute all further
passes. This would only occur if $debug was set, otherwise the code
would never be evaled, and we wouldn’t even test to see if the verbose
flag was set, and thus it would never actually get executed. I suppose
this could also be simulated if we had constant propagation in the
interpreter, so that a constant if expression would be eliminated.

Another comment though, I really hate having only the ability to turn
debug output off globally. It’s much nicer to be able to turn it all on
or off, but also be able to turn it on per the scope you are in.

Charlie

···

On Wed, 25 Feb 2004 15:38:53 +0100, Robert Klemme wrote:


(Robert) #13

“Charles Comstock” cc1@cec.wustl.edu schrieb im Newsbeitrag
news:c1jbfq$eiv$1@newsreader.wustl.edu

Simon Strandgaard wrote:

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag

Any ideas for a good name?

debug replacement puts -> #debug_puts, #dputs
debug replacement p -> #debug_p, #dp

Hm… I’d go for “d_puts” which is immediately distinguished from
"puts"

but is not so much typing overhead as the more verbose “debug_puts”.

maybe just turn the ‘p’ in ‘puts’ upsidedown, so it becomes a ‘d’ =>

duts?

http://www.best-lyrics-zone.net/Upside_Down_Lyrics.html
:slight_smile:

BTW: I had to change my taste of music so it reflect the language I am
using

diamonds are forever
lucy in the sky with diamonds
diamonds are a girls best friend


Simon Strandgaard

It would be nice if we had macros for the debug stuff, so the code would
never even be seen when you didn’t do debug code. For instance if
instead for debug output you had a debug block, which was evaled and
added to the code on the first pass, so it would execute all further
passes. This would only occur if $debug was set, otherwise the code
would never be evaled, and we wouldn’t even test to see if the verbose
flag was set, and thus it would never actually get executed. I suppose
this could also be simulated if we had constant propagation in the
interpreter, so that a constant if expression would be eliminated.

I don’t mandate a preprocessor since Ruby is flexible enough and we all
know what Bjarne said about one of his biggest mistakes with C++… :slight_smile:

IMHO this is as efficient as it can get without a macro preprocessor. The
overhead is a single method call and a boolean test for non debug mode:

module Kernel
def debug
yield if $DEBUG
end
end

Then you can do:

def foo
debug {
# complex calculations might be here
}

normal operation

end

Another comment though, I really hate having only the ability to turn
debug output off globally. It’s much nicer to be able to turn it all on
or off, but also be able to turn it on per the scope you are in.

That’s what Simon’s suggestion was all about. :slight_smile:

robert
···

On Wed, 25 Feb 2004 15:38:53 +0100, Robert Klemme wrote: