Another take on ensuring right args to methods

Since #respond_to? only checks whether an object responds to a call,
not what it does in response; since #can? as an alias to #respond_to?
would be misleading in that it wouldn’t really check what the object
does; since typing a la C or Java takes much away from the language
and is no better indicator of the real behaviour of an object; what
about this?

class Foo
def meth(bar)
bar.passes?(TestBar) or raise ArgumentError
end
end
Foo.new.meth(1)

$ ruby --inline-tests foo.rb

Just a thought.

Massimiliano

Hi –

Since #respond_to? only checks whether an object responds to a call,
not what it does in response; since #can? as an alias to #respond_to?
would be misleading in that it wouldn’t really check what the object
does; since typing a la C or Java takes much away from the language
and is no better indicator of the real behaviour of an object; what
about this?

Personally I like #can? but it doesn’t help with the awkward two-headed
“obj.meth if obj.can?(:meth)” idiom.

class Foo def meth(bar) bar.passes?(TestBar) or raise ArgumentError
end end Foo.new.meth(1) $ ruby --inline-tests foo.rb

What does #passes? actually do?

David

···

On Sun, 6 Oct 2002, Massimiliano Mirra wrote:


David Alan Black | Register for RubyConf 2002!
home: dblack@candle.superlink.net | November 1-3
work: blackdav@shu.edu | Seattle, WA, USA
Web: http://pirate.shu.edu/~blackdav | http://www.rubyconf.com

Personally I like #can? but it doesn’t help with the awkward two-headed
“obj.meth if obj.can?(:meth)” idiom.

class Foo def meth(bar) bar.passes?(TestBar) or raise ArgumentError
end end Foo.new.meth(1) $ ruby --inline-tests foo.rb

What does #passes? actually do?

I’m guessing it runs some suite of unit tests and returns true IFF all of them
pass.

Personally I like #can? but it doesn’t help with the awkward two-headed
“obj.meth if obj.can?(:meth)” idiom.

I know, but I’m still convinced that you’d only want to do that when
calling meth on obj was totally optional to the logic, which happens
seldom (at least in my experience).

class Foo def meth(bar) bar.passes?(TestBar) or raise ArgumentError
end end Foo.new.meth(1) $ ruby --inline-tests foo.rb
What does #passes? actually do?

Actually nothing since it’s not implemented :-), but in my mind, it
would submit the object (or rather its class) to a small ad-hoc test
suite, which would not only test whether it responded to (for example)
#read, #write and #seek, but also check whether what gets written with
#write can be later read with #read.

It would impose quite an overhead at runtime, but could be executed
only when a global switch was turned on (–inline-tests), and would
guarantee that an object really provides some functionality, not just
`looks like to’ as with respond_to? or Java interfaces.

Massimiliano

···

On Sun, Oct 06, 2002 at 10:43:46PM +0900, dblack@candle.superlink.net wrote:

Personally I like #can? but it doesn’t help with the awkward two-headed
“obj.meth if obj.can?(:meth)” idiom.

I know, but I’m still convinced that you’d only want to do that when
calling meth on obj was totally optional to the logic, which happens
seldom (at least in my experience).

class Foo def meth(bar) bar.passes?(TestBar) or raise ArgumentError
end end Foo.new.meth(1) $ ruby --inline-tests foo.rb
What does #passes? actually do?

Actually nothing since it’s not implemented :-), but in my mind, it
would submit the object (or rather its class) to a small ad-hoc test
suite, which would not only test whether it responded to (for example)
#read, #write and #seek, but also check whether what gets written with
#write can be later read with #read.

What if the object represents /dev/null and you cannot read back what you
wrote previously? It is hard to specify the right minimal semantic
requirements…

It would impose quite an overhead at runtime, but could be executed
only when a global switch was turned on (–inline-tests), and would
guarantee that an object really provides some functionality, not just
`looks like to’ as with respond_to? or Java interfaces.

IMHO it is a good idea if some provision is made for “non-standard”
behaving objects.

···

On Mon, Oct 07, 2002 at 05:15:05PM +0900, Massimiliano Mirra wrote:

On Sun, Oct 06, 2002 at 10:43:46PM +0900, dblack@candle.superlink.net wrote:


Mauricio Julio Fernandez Pradier

I am collecting a users’s email address from a web form and trying to
created and .rb smtp application to dynaically generate an e-mail…I
have tried inserting the cgi email variable into my string but I am
running into problems…

I have tried the following

email = params[‘email’][0]

f.puts ‘From: inforequest@test.com on behalf of <%= email %>’
and
f.puts ‘From: inforequest@test.com on behalf of #{email}’

Any input on how to correctly insert this param in the string would be
greatly appreciated…

thanks
Jeff

···

Hi –

Personally I like #can? but it doesn’t help with the awkward two-headed
“obj.meth if obj.can?(:meth)” idiom.

I know, but I’m still convinced that you’d only want to do that when
calling meth on obj was totally optional to the logic, which happens
seldom (at least in my experience).

Or if you’re branching:

if obj.respond_to?(x)
obj.x
elsif obj.respond_to?(y)
obj.y

end

which is probably a sign of a design flaw… but the project that
originally got me thinking about a lot of this stuff, a year or so
ago, was one where I ended up doing something like the above (and not
liking it :slight_smile:

David

···

On Mon, 7 Oct 2002, Massimiliano Mirra wrote:

On Sun, Oct 06, 2002 at 10:43:46PM +0900, dblack@candle.superlink.net wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

f.puts 'From: inforequest@test.com on behalf of #{email}'

#{...} is interpolated in double quoted string (i.e. "")

  f.puts "From: inforequest@test.com on behalf of #{email}"

Guy Decoux

would submit the object (or rather its class) to a small ad-hoc test
suite, which would not only test whether it responded to (for example)
#read, #write and #seek, but also check whether what gets written with
#write can be later read with #read.

What if

Oh, I knew it was coming… :wink:

the object represents /dev/null and you cannot read back what you
wrote previously?

If the method needs to read back, you’ve just caught a bug; if it does
not need to read back, you’re running the wrong test.

It is hard to specify the right minimal semantic requirements…

Anything in particular makes you think so?

It would impose quite an overhead at runtime, but could be executed
only when a global switch was turned on (–inline-tests), and would
guarantee that an object really provides some functionality, not just
`looks like to’ as with respond_to? or Java interfaces.

IMHO it is a good idea if some provision is made for “non-standard”
behaving objects.

I wasn’t suggesting standard tests – that would be equivalent to
going back to type names; I was suggesting ad-hoc tests made up
according to the needs of the method.

Massimiliano

···

On Tue, Oct 08, 2002 at 05:52:46PM +0900, Mauricio Fernández wrote:

would submit the object (or rather its class) to a small ad-hoc test
suite, which would not only test whether it responded to (for example)
#read, #write and #seek, but also check whether what gets written with
#write can be later read with #read.

What if

Oh, I knew it was coming… :wink:

the object represents /dev/null and you cannot read back what you
wrote previously?

If the method needs to read back, you’ve just caught a bug; if it does
not need to read back, you’re running the wrong test.

It is hard to specify the right minimal semantic requirements…

Anything in particular makes you think so?

I only needed about .1s to find the /dev/null example. There must be
tons of them. If you completely specify the semantics of something, it
is too constrained, for somebody could find another use for it you
didn’t think of.

It would impose quite an overhead at runtime, but could be executed
only when a global switch was turned on (–inline-tests), and would
guarantee that an object really provides some functionality, not just
`looks like to’ as with respond_to? or Java interfaces.

IMHO it is a good idea if some provision is made for “non-standard”
behaving objects.

I wasn’t suggesting standard tests – that would be equivalent to
going back to type names; I was suggesting ad-hoc tests made up
according to the needs of the method.

We’d need a summary of “best current practice” for this kind of tests so
you don’t make too many assumptions.

···

On Wed, Oct 09, 2002 at 06:35:18AM +0900, Massimiliano Mirra wrote:

On Tue, Oct 08, 2002 at 05:52:46PM +0900, Mauricio Fernández wrote:

Massimiliano


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Q: What’s the big deal about rm, I have been deleting stuff for years? And
never lost anything… oops!
A: …
– From the Frequently Unasked Questions

the object represents /dev/null and you cannot read back what you
wrote previously?
If the method needs to read back, you’ve just caught a bug; if it does
not need to read back, you’re running the wrong test.

It is hard to specify the right minimal semantic requirements…

Anything in particular makes you think so?

I only needed about .1s to find the /dev/null example.

Now if only it showed something…

There must be
tons of them. If you completely specify the semantics of something, it
is too constrained, for somebody could find another use for it you
didn’t think of.

Then don’t specify it completely.

IMHO it is a good idea if some provision is made for “non-standard”
behaving objects.

I wasn’t suggesting standard tests – that would be equivalent to
going back to type names; I was suggesting ad-hoc tests made up
according to the needs of the method.

We’d need a summary of “best current practice” for this kind of tests so
you don’t make too many assumptions.

We’d need a summary of “best current practice” for lots of things we
do daily. :slight_smile:

Massimiliano

···

On Thu, Oct 10, 2002 at 02:45:12AM +0900, Mauricio Fernández wrote: