Announcing Reg 0.4.0

Florian Groß <florgro@gmail.com> writes:

David A. Black wrote:

extending the system so that it could match, for example,
"an array of objects that respond to ''" (or something along those
lines)?

I wonder if he could just support objects that implement === which
would give you Range and Module support and ruby-contract support for
free.

But how is this related to your quote at all? ruby-contract offers a Check::Quack[:message] adaptor that implements === via respond_to?() --
I wonder if it would be a good idea to define Symbol#=== which would
be used like this:

first = case obj
   when :first then
     obj.first
   when :fetch then
     obj.fetch(0)
   when :at then
     obj.at(0)
   when : then
     obj[0]
end

While I can see your intention, please don't do that. Often, people
want to compare Symbols and Symbols (they are perfect for that). It
is already very confusing that String !=== String (what is the most
elegant way to case compare classes against classes, btw?).

case obj.quack
  when :first
  when :fetch
  ...
end

would be nice to have, though.

···

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org

Florian Groß wrote:

I wonder if he could just support objects that implement ===
which would give you Range and Module support and ruby-
contract support for free.

And in fact, this is exactly what I did. The idea is that users can
easily create their own (scalar) matchers by writing a matcher class
and implementing === in it. This also gives you automatic support for
all the library classes that have ===.

I'm going to have to check out this ruby-contract thing. Sounds very
interesting.

Hi --

I wrote:

I'm not sure about Christian, but I think itsme213 meant
sort of the opposite: how does your system relate to the
duck-typing environment of Ruby, where type != class
(i.e., an object's capabilities and its class's instance
methods are not necessarily the same thing)? Are you
thinking of extending the system so that it could match,
for example, "an array of objects that respond to ''"

Oh! Ok, well that's easy, it would be something like:

+[ proceq{|x| x.respond_to? : }+1 ]

Being forced to use a proceq (gawd that's a terrible name) here is a
little ugly. Eventually, I want to be able to pass arguments to
property matchers, so the above could be:

+[ -{ [:respond_to?, :]=>true }+1 ]

I wonder whether one could combine this with tests for class ancestry,
by matching a class/module name (#is_a?) and, at the same time,
verifying that the object's capabilities are a match for its ancestry.
Or something. I haven't puzzled it through very deeply.

duck typing per se, as I understand it, really means just
requesting action from objects without a lot of preliminary
querying and measuring (whether it be is_a?, respond_to?,
or whatever).

If you're doing something complicated, you occasionally have to
explicity request the type (whether duck- or class-) of objects you're
working with, in order to do the right thing with it. I know this isn't
polymorphic, but sometimes it is the right way...

I'd tend to say: if it's the type, it's not the class, and if you have
to explicitly request it, it's not duck-typing :slight_smile: But yes, I think
there are occasions for all these things, in various combinations.
As others have often pointed out, respond_to? != duck typing, but I do
tend to think of respond_to?-based logic as a kind of "weak duck
typing", if that isn't too arcane. It falls short of the true "Here,
do this!" spirit of true duck typing, but undeniably (in my view) has
a foot in the same camp, in that it factors in the dynamism of type.

David

···

On Wed, 27 Apr 2005, vikkous wrote:

--
David A. Black
dblack@wobblini.net

Christian Neukirchen wrote:

While I can see your intention, please don't do that. Often,
people want to compare Symbols and Symbols (they are
perfect for that). It is already very confusing that String
!=== String (what is the most elegant way to case
compare classes against classes, btw?).

The correct operator to use for comparison is ==, not ===. Despite the
similarity of names, === is for pattern-matching, not comparison. For
simple classes, pattern-matching and comparison are the same thing, but
when the receiver is a Regexp, or a Reg, things are different.

Btw,
  :sym==:sym and Class==Class
work just fine.

case obj.quack
  when :first
  when :fetch
  ...
end

would be nice to have, though.

hmmm... I haven't tried this, but....

require 'reg'

class Object
  def quack
    RegOr.new *methods
  end
end

ought to do it

I don't know about elegant, but this is probably the way that requires least typing:

def make_new(klass)
   case [klass]
     when [String]: "foo"
     when [Fixnum]: 27
     when [Array]: [nil, nil, true]
   end
end

make_new String
=> "foo"

Ilmari Heikkinen

···

On 26.4.2005, at 20:35, Christian Neukirchen wrote:

It is already very confusing that String !=== String (what is the most
elegant way to case compare classes against classes, btw?).

--
66. The regions beyond these places are either difficult of access because of their excessive winters and great cold, or else cannot be sought out because, of some divine influence of the gods.

vikkous said:

require 'reg'

class Object
  def quack
   RegOr.new *methods
  end
end

Well, not quite. If Florian's Symbol#=== existed it would work,
otherwise it has to be like:

require 'reg'

class Object
  def quack
    RegOr.new *methods.map{|m| proceq{|x| x.respond_to? m } }
  end
end

"vikkous" <google@inforadical.net> writes:

Christian Neukirchen wrote:

While I can see your intention, please don't do that. Often,
people want to compare Symbols and Symbols (they are
perfect for that). It is already very confusing that String
!=== String (what is the most elegant way to case
compare classes against classes, btw?).

The correct operator to use for comparison is ==, not ===. Despite the
similarity of names, === is for pattern-matching, not comparison. For
simple classes, pattern-matching and comparison are the same thing, but
when the receiver is a Regexp, or a Reg, things are different.

Btw,
  :sym==:sym and Class==Class
work just fine.

Yes, they do. But case compares with ===.

···

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org

Ilmari Heikkinen <kig@misfiring.net> writes:

It is already very confusing that String !=== String (what is the most
elegant way to case compare classes against classes, btw?).

I don't know about elegant, but this is probably the way that requires
least typing:

def make_new(klass)
   case [klass]
     when [String]: "foo"
     when [Fixnum]: 27
     when [Array]: [nil, nil, true]
   end
end

make_new String
=> "foo"

Nice, that conses a lot but is readable and understandable. Thanks!

···

On 26.4.2005, at 20:35, Christian Neukirchen wrote:

Ilmari Heikkinen

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org