[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Its Me

11/12/2004 6:51:00 PM

I could not find a standard "assert" in Ruby. Is there one?

Thanks!



28 Answers

Eric Hodel

11/12/2004 7:54:00 PM

0

On Nov 12, 2004, at 10:53 AM, itsme213 wrote:

> I could not find a standard "assert" in Ruby. Is there one?

Outside of Test::Unit

raise "message" if condition

and

raise "meassge" unless condition



Edgardo Hames

11/12/2004 8:10:00 PM

0

On Sat, 13 Nov 2004 03:53:27 +0900, itsme213 <itsme213@hotmail.com> wrote:
> I could not find a standard "assert" in Ruby. Is there one?
>

I asked a similar question some time ago. This is the thread:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-t...

Kind Regards,
Ed
--
Despite the surge of power you feel upon learning Ruby,
resist the urge to trip others or slap them in the bald head.
DO NOT LORD YOUR RUBYNESS OVER OTHERS!


Mohammad Khan

11/12/2004 8:24:00 PM

0

On Fri, 2004-11-12 at 15:09, Edgardo Hames wrote:
> On Sat, 13 Nov 2004 03:53:27 +0900, itsme213 <itsme213@hotmail.com> wrote:
> > I could not find a standard "assert" in Ruby. Is there one?
> >
>
> I asked a similar question some time ago. This is the thread:
>
> http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-t...
>
> Kind Regards,
> Ed

"Despite the surge of power you feel upon learning Ruby,
resist the urge to trip others or slap them in the bald head.
DO NOT LORD YOUR RUBYNESS OVER OTHERS!"


This is the most wonderful quote I ever heard about ruby.
sorry to write off-topic .

--
Mohammad





Florian Gross

11/12/2004 8:27:00 PM

0

itsme213 wrote:

> I could not find a standard "assert" in Ruby. Is there one?

There's one in the dev-utils package. It will automatically set a
breakpoint if the application is run in debug mode and therefore give
you an irb shell where you can find out why your assert failed.

Edgardo Hames

11/12/2004 9:50:00 PM

0

On Sat, 13 Nov 2004 05:24:15 +0900, Mohammad Khan <mkhan@lextranet.com> wrote:
> On Fri, 2004-11-12 at 15:09, Edgardo Hames wrote:
>
>
> > On Sat, 13 Nov 2004 03:53:27 +0900, itsme213 <itsme213@hotmail.com> wrote:
> > > I could not find a standard "assert" in Ruby. Is there one?
> > >
> >
> > I asked a similar question some time ago. This is the thread:
> >
> > http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-t...
> >
> > Kind Regards,
> > Ed
>
> "Despite the surge of power you feel upon learning Ruby,
> resist the urge to trip others or slap them in the bald head.
> DO NOT LORD YOUR RUBYNESS OVER OTHERS!"
>
> This is the most wonderful quote I ever heard about ruby.
> sorry to write off-topic .
>

Qbviously, this quote belongs to why the lucky stiff. Today I feel
like searching back in old mails...;) Please, see this thread:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-t...

Regards,
Ed
--
Despite the surge of power you feel upon learning Ruby,
resist the urge to trip others or slap them in the bald head.
DO NOT LORD YOUR RUBYNESS OVER OTHERS!


Its Me

11/13/2004 12:33:00 AM

0

> There's one in the dev-utils package. It will automatically set a
> breakpoint if the application is run in debug mode and therefore give
> you an irb shell where you can find out why your assert failed.

That would work nice ... but I could not find it.


Gavin Sinclair

11/13/2004 1:46:00 AM

0

On Saturday, November 13, 2004, 7:28:26 AM, Florian wrote:

> itsme213 wrote:

>> I could not find a standard "assert" in Ruby. Is there one?

> There's one in the dev-utils package. It will automatically set a
> breakpoint if the application is run in debug mode and therefore give
> you an irb shell where you can find out why your assert failed.

It's not there at the moment (I don't think). And the OP probably
wants an exception raised, not an IRB session :)

Cheers,
Gavin



Gavin Sinclair

11/13/2004 2:00:00 AM

0

On Saturday, November 13, 2004, 12:46:23 PM, Gavin wrote:

> On Saturday, November 13, 2004, 7:28:26 AM, Florian wrote:

>> itsme213 wrote:

>>> I could not find a standard "assert" in Ruby. Is there one?

>> There's one in the dev-utils package. It will automatically set a
>> breakpoint if the application is run in debug mode and therefore give
>> you an irb shell where you can find out why your assert failed.

> It's not there at the moment (I don't think). And the OP probably
> wants an exception raised, not an IRB session :)

While writing that message, I realised why a breakpoint-inducing
assert would be handy. Let's call it assert_bp, since the bare name
'assert' so strongly implies "raise an error if expression is false".

Code:

x = 5
y = 6
assert_bp "x + y = 100"

Console:

Assert failed: x + y = 100 (foo/bar.rb:51)
irb> _

Now, can anyone suggest a better name than 'assert_bp'?

Gavin






Its Me

11/13/2004 2:24:00 AM

0

> Now, can anyone suggest a better name than 'assert_bp'?

assert?

i.e. tentative assert :)

though i would use it everywhere by default. it would be nice if there were
a couple of eiffel-like switches to modify its behavior.


Florian Gross

11/13/2004 8:37:00 AM

0

itsme213 wrote:

>>There's one in the dev-utils package. It will automatically set a
>>breakpoint if the application is run in debug mode and therefore give
>>you an irb shell where you can find out why your assert failed.
> That would work nice ... but I could not find it.

Oh, you are right. It is not yet included in dev-utils because of its
name. I have attached my local version of breakpoint.rb which includes it.

I have thought about changing the name to "assume" so it can be included
in dev-utils, but I'm not sure if that name is better.
require 'breakpoint'
require 'optparse'

options = {
:ClientURI => nil,
:ServerURI => "druby://localhost:42531",
:RetryDelay => 10
}

ARGV.options do |opts|
script_name = File.basename($0)
opts.banner = [
"Usage: ruby #{script_name} [options] [server uri]",
"",
"This tool lets you connect to a breakpoint service ",
"which was started via Breakpoint.activate_drb.",
"",
"The server uri defaults to druby://localhost:42531"
].join("\n")

opts.separator ""

opts.on("-c", "--client-uri=uri",
"Run the client on the specified uri.",
"This can be used to specify the port",
"that the client uses to allow for back",
"connections from the server.",
"Default: Find a good URI automatically.",
"Example: -c druby://localhost:12345"
) { |options[:ClientURI]| }

opts.on("-s", "--server-uri=uri",
"Connect to the server specified at the",
"specified uri.",
"Default: druby://localhost:42531"
) { |options[:ServerURI]| }

opts.on("-R", "--retry-delay=delay", Integer,
"Automatically try to reconnect to the",
"server after delay seconds when the",
"connection failed or timed out.",
"A value of 0 disables automatical",
"reconnecting completely.",
"Default: 10"
) { |options[:RetryDelay]| }

opts.separator ""

opts.on("-h", "--help",
"Show this help message."
) { puts opts; exit }

opts.parse!
end

options[:ServerURI] = ARGV[0] if ARGV[0]

DRb.start_service(options[:ClientURI])

begin
service = DRbObject.new(nil, options[:ServerURI])

begin
service.register_handler do |workspace, message|
puts message
IRB.start(nil, nil, workspace)
end

service.register_exit_handler do
# Need to delay this because server expects a response
Thread.new do
puts "Received shut down signal."
sleep 1
exit!
end

nil
end

sleep
ensure
service.unregister_handler
service.unregister_exit_handler
end
rescue Exception => error
if options[:RetryDelay] > 0 then
puts "No connection to breakpoint service at #{options[:ServerURI]}:",
" (#{error})",
" Reconnecting in #{options[:RetryDelay]} seconds..."

sleep options[:RetryDelay]
retry
else
raise
end
end
begin
require 'simplecc'
rescue LoadError
def Continuation.create(*args, &block)
cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?}
result ||= args
return *[cc, *result]
end
end

# This method returns the binding of the method that called your
# method. It will raise an Exception when you're not inside a method.
#
# It's used like this:
# def inc_counter(amount = 1)
# Binding.of_caller do |binding|
# # Create a lambda that will increase the variable 'counter'
# # in the caller of this method when called.
# inc = eval("lambda { |arg| counter += arg }", binding)
# # We can refer to amount from inside this block safely.
# inc.call(amount)
# end
# # No other statements can go here. Put them inside the block.
# end
# counter = 0
# 2.times { inc_counter }
# counter # => 2
#
# Binding.of_caller must be the last statement in the method.
# This means that you will have to put everything you want to
# do after the call to Binding.of_caller into the block of it.
# This should be no problem however, because Ruby has closures.
# If you don't do this an Exception will be raised. Because of
# the way that Binding.of_caller is implemented it has to be
# done this way.
def Binding.of_caller(&block)
old_critical = Thread.critical
Thread.critical = true
count = 0
cc, result, error, extra_data = Continuation.create(nil, nil)
error.call if error

tracer = lambda do |*args|
type, context, extra_data = args[0], args[4], args
if type == "return"
count += 1
# First this method and then calling one will return --
# the trace event of the second event gets the context
# of the method which called the method that called this
# method.
if count == 2
# It would be nice if we could restore the trace_func
# that was set before we swapped in our own one, but
# this is impossible without overloading set_trace_func
# in current Ruby.
set_trace_func(nil)
cc.call(eval("binding", context), nil, extra_data)
end
elsif type != "line"
set_trace_func(nil)
error_msg = "Binding.of_caller used in non-method context or " +
"trailing statements of method using it aren't in the block."
cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil)
end
end

unless result
set_trace_func(tracer)
return nil
else
Thread.critical = old_critical
case block.arity
when 1 then yield(result)
else yield(result, extra_data)
end
end
end
require 'irb'
require 'binding_of_caller'
require 'drb'

module Breakpoint
extend self

# This will pop up an interactive ruby session at a
# pre-defined break point in a Ruby application. In
# this session you can examine the environment of
# the break point.
#
# You can get a list of variables in the context using
# local_variables via +local_variables+. You can then
# examine their values by typing their names.
#
# You can have a look at the call stack via +caller+.
#
# The source code around the location where the breakpoint
# was executed can be examined via +source_lines+. Its
# argument specifies how much lines of context to display.
# The default amount of context is 5 lines. Note that
# the call to +source_lines+ can raise an exception when
# it isn't able to read in the source code.
#
# breakpoints can also return a value. They will execute
# a supplied block for getting a default return value.
# A custom value can be returned from the session by doing
# +throw(:debug_return, value)+.
#
# You can also give names to break points which will be
# used in the message that is displayed upon execution
# of them.
#
# Here's a sample of how breakpoints should be placed:
#
# class Person
# def initialize(name, age)
# @name, @age = name, age
# breakpoint("Person#initialize")
# end
#
# attr_reader :age
# def name
# breakpoint("Person#name") { @name }
# end
# end
#
# person = Person.new("Random Person", 23)
# puts "Name: #{person.name}"
#
# And here is a sample debug session:
#
# Executing break point "Person#initialize" at file.rb:4 in `initialize'
# irb(#<Person:0x292fbe8>):001:0> local_variables
# => ["name", "age", "_", "__"]
# irb(#<Person:0x292fbe8>):002:0> [name, age]
# => ["Random Person", 23]
# irb(#<Person:0x292fbe8>):003:0> [@name, @age]
# => ["Random Person", 23]
# irb(#<Person:0x292fbe8>):004:0> self
# => #<Person:0x292fbe8 @age=23, @name="Random Person">
# irb(#<Person:0x292fbe8>):005:0> @age += 1; self
# => #<Person:0x292fbe8 @age=24, @name="Random Person">
# irb(#<Person:0x292fbe8>):006:0> exit
# Executing break point "Person#name" at file.rb:9 in `name'
# irb(#<Person:0x292fbe8>):001:0> throw(:debug_return, "Overriden name")
# Name: Overriden name
def breakpoint(id = nil, context = nil, &block)
callstack = caller
callstack.slice!(0, 3) if callstack.first["breakpoint"]
file, line, method = *callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/).captures

message = "Executing break point " + (id ? "#{id.inspect} " : "") +
"at #{file}:#{line}" + (method ? " in `#{method}'" : "")

if context then
return handle_breakpoint(context, message, file, line, &block)
end

Binding.of_caller do |binding_context|
handle_breakpoint(binding_context, message, file, line, &block)
end
end

def handle_breakpoint(context, message, file = "", line = "", &block) # :nodoc:
catch(:debug_return) do |value|
eval(%{
def self.source_lines(context = 5, return_line_numbers = false)
lines = File.readlines(#{file.inspect}).map { |line| line.chomp }

break_line = #{line}
start_line = [break_line - context, 1].max
end_line = break_line + context

result = lines[(start_line - 1) .. (end_line - 1)]

if return_line_numbers then
return [start_line, break_line, result]
else
return result
end
end
}, context) rescue nil

if not use_drb? then
puts message
IRB.start(nil, IRB::WorkSpace.new(context))
else
@drb_service.add_breakpoint(context, message)
end

block.call if block
end
end
private :handle_breakpoint

# This asserts that the block evaluates to true.
# If it doesn't evaluate to true a breakpoint will
# automatically be created at that execution point.
#
# You can disable assert checking by setting
# Breakpoint.optimize_asserts to true before
# loading the breakpoint.rb library. (It will still
# be enabled when Ruby is run via the -d argument.)
#
# Example:
# person_name = "Foobar"
# assert { not person_name.nil? }
def assert(context = nil, &condition)
return if Breakpoint.optimize_asserts and not $DEBUG
return if yield

callstack = caller
callstack.slice!(0, 3) if callstack.first["assert"]
file, line, method = *callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/).captures

message = "Assert failed at #{file}:#{line}#{" in `#{method}'" if method}. " +
"Executing implicit breakpoint."

if context then
return handle_breakpoint(context, message, file, line)
end

Binding.of_caller do |context|
handle_breakpoint(context, message, file, line)
end
end

# Whether asserts should be ignored if not in debug mode.
# Debug mode can be enabled by running ruby with the -d
# switch or by setting $DEBUG to true.
attr_accessor :optimize_asserts
self.optimize_asserts = false

class DRbService
include DRbUndumped

def initialize
@handler = nil
@at_exit = lambda { }

IRB.instance_eval { @CONF[:RC] = true }
IRB.run_config

at_exit { @at_exit.call }
end

def add_breakpoint(context, message)
workspace = IRB::WorkSpace.new(context)
workspace.extend(DRbUndumped)

until @handler; end
@handler.call(workspace, message)
end

def register_handler(&block)
@handler = block
end

def unregister_handler
@handler = nil
end

def register_exit_handler(&block)
@at_exit = block
end

def unregister_exit_handler
@at_exit = lambda { }
end
end

# Will run Breakpoint in DRb mode. This will spawn a server
# that can be attached to via the breakpoint-client command
# whenever a breakpoint is executed. This is useful when you
# are debugging CGI applications or other applications where
# you can't access debug sessions via the standard input and
# output of your application.
#
# You can specify an URI where the DRb server will run at.
# This way you can specify the port the server runs on. The
# default URI is druby://localhost:42531.
#
# Please note that breakpoints will be skipped silently in
# case the DRb server can not spawned. (This can happen if
# the port is already used by another instance of your
# application on CGI or another application.)
#
# Also note that by default this is not secure. You can
# however specify a list of allowed hosts. But that will
# still not protect you from somebody reading the data
# as it goes through the net.
#
# A good approach for getting security is setting up an SSH
# tunnel between the DRb service and the client. This is
# usually done like this:
#
# $ ssh -L20000:127.0.0.1:20000 -R10000:127.0.0.1:10000 example.com
# (This will connect port 20000 at the client side to port
# 20000 at the server side, and port 10000 at the server
# side to port 10000 at the client side.)
#
# After you have done that you should specify "localhost"
# as the second argument to the +activate_drb()+ call.
#
# Running through such a SSH proxy will also let you use
# breakpoint.rb in case you are behind a firewall.
#
# Detailed information about running DRb through firewalls is
# available at http://www.rubygarden.org/ruby?D...
def activate_drb(uri = 'druby://localhost:42531',
allowed_hosts = nil)

if allowed_hosts then
acl = ["deny all"]

Array(allowed_hosts).each do |host|
acl << "allow #{host}"
end

DRb.install_acl(ACL.new(acl.join("\n")))
end

@use_drb = true
@drb_service = DRbService.new
DRb.start_service(uri, @drb_service)
end

def use_drb?
@use_drb == true
end
end

module IRB
def IRB.start(ap_path = nil, main_context = nil, workspace = nil)
$0 = File::basename(ap_path, ".rb") if ap_path

# suppress some warnings about redefined constants
old_verbose, $VERBOSE = $VERBOSE, nil
IRB.setup(ap_path)
$VERBOSE = old_verbose

if @CONF[:SCRIPT] then
irb = Irb.new(main_context, @CONF[:SCRIPT])
else
irb = Irb.new(main_context)
end

if workspace then
irb.context.workspace = workspace
end

@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
@CONF[:MAIN_CONTEXT] = irb.context

trap("SIGINT") do
irb.signal_handle
end

catch(:IRB_EXIT) do
irb.eval_input
end
end

class << self; alias :old_CurrentContext :CurrentContext; end
def IRB.CurrentContext
if old_CurrentContext.nil? and Breakpoint.use_drb? then
result = Object.new
def result.last_value; end
return result
else
old_CurrentContext
end
end

class Context
alias :old_evaluate :evaluate
def evaluate(line, line_no)
if line.chomp == "exit" then
exit
else
old_evaluate(line, line_no)
end
end
end

class WorkSpace
alias :old_evaluate :evaluate

def evaluate(*args)
if Breakpoint.use_drb? then
result = old_evaluate(*args)
unless [true, false, nil].include?(result)
result.extend(DRbUndumped) rescue nil
end
return result
else
old_evaluate(*args)
end
end
end
end

class DRb::DRbObject
undef :inspect
end

def breakpoint(id = nil, &block)
Binding.of_caller do |context|
Breakpoint.breakpoint(id, context, &block)
end
end

def assert(&block)
Binding.of_caller do |context|
Breakpoint.assert(context, &block)
end
end