[RCR] array or with non-array

  • Thread starter Simon Strandgaard
  • Start date
S

Simon Strandgaard

Sometimes wish that [3, 5, 13] | [8] can be written as [3, 5, 13] | 8
that ary |=3D 42 would be possible.

chris2 pointed out that it would be inconsistent with [1,2,3] + 4.
maybe let + append 4 to the array?



ary =3D [1, 3, 4]
#=3D> [1, 3, 4]

ary |=3D 2
#=3D> [1, 2, 3, 4]



This is another bad idea..
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: [RCR] array or with non-array"

|Sometimes wish that [3, 5, 13] | [8] can be written as [3, 5, 13] | 8
|that ary |= 42 would be possible.
|
|chris2 pointed out that it would be inconsistent with [1,2,3] + 4.
|maybe let + append 4 to the array?

Too much conversion sometimes makes troubles, or hides troubles, for
example, Ruby used to convert string and numbers more eagerly, but I
stopped that to get a chance to detect human errors.

But I'm not sure this conversion is harmless and useful, or not. Let
us try for a while. Here's a patch to implement what you want. I
will merge it to the HEAD, to see how it goes.

matz.

diff -p -u -1 -r1.173 array.c
--- array.c 5 Jul 2005 14:23:22 -0000 1.173
+++ array.c 2 Aug 2005 22:01:43 -0000
@@ -304,2 +304,13 @@ to_ary(ary)
static VALUE
+make_ary(ary)
+ VALUE ary;
+{
+ VALUE tmp = rb_check_array_type(ary);
+ if (NIL_P(tmp)) {
+ return rb_ary_new3(1, ary);
+ }
+ return tmp;
+}
+
+static VALUE
to_a(ary)
@@ -2346,6 +2357,12 @@ rb_ary_plus(x, y)
{
- VALUE z;
+ VALUE tmp, z;
long len;

- y = to_ary(y);
+ tmp = rb_check_array_type(y);
+ if (NIL_P(tmp)) {
+ z = rb_ary_dup(x);
+ rb_ary_push(z, y);
+ return z;
+ }
+ y = tmp;
len = RARRAY(x)->len + RARRAY(y)->len;
@@ -2696,6 +2713,6 @@ rb_ary_diff(ary1, ary2)
{
- VALUE ary3, hash;
+ VALUE tmp, ary3, hash;
long i;

- hash = ary_make_hash(to_ary(ary2), 0);
+ hash = ary_make_hash(make_ary(ary2), 0);
ary3 = rb_ary_new();
@@ -2727,5 +2744,5 @@ rb_ary_and(ary1, ary2)

- ary2 = to_ary(ary2);
+ ary2 = make_ary(ary2);
ary3 = rb_ary_new2(RARRAY(ary1)->len < RARRAY(ary2)->len ?
- RARRAY(ary1)->len : RARRAY(ary2)->len);
+ RARRAY(ary1)->len : RARRAY(ary2)->len);
hash = ary_make_hash(ary2, 0);
@@ -2761,3 +2778,3 @@ rb_ary_or(ary1, ary2)

- ary2 = to_ary(ary2);
+ ary2 = make_ary(ary2);
ary3 = rb_ary_new2(RARRAY(ary1)->len+RARRAY(ary2)->len);
 
E

Eric Mahurin

--- Simon Strandgaard said:
Sometimes wish that [3, 5, 13] | [8] can be written as [3,
5, 13] | 8
that ary |=3D 42 would be possible.
=20
chris2 pointed out that it would be inconsistent with [1,2,3]
+ 4.
maybe let + append 4 to the array?
=20
=20
=20
ary =3D [1, 3, 4]
#=3D> [1, 3, 4]
=20
ary |=3D 2
#=3D> [1, 2, 3, 4]
=20
=20
=20
This is another bad idea..


Are you suggesting this or saying it is bad?

I don't like it at all. So this is suggesting 2 forms to
Array#| and Array#+:

array | other_array =3D> array
array | element =3D> array

If you are looking at combining an element that happens to also
be an array, you have an ambiguous situation. It will combine
the contents of that array instead of the array.

If you want this functionality, you should ask for another
method that does this instead of overloading another. There is
no disadvantage to this other than having to remember a new
method name (and not being able to reuse an operator). The
problem is that there is a decision to be made about what to do
(combine a single element or an array of them) and that
decision is based on what the argument type is (or what methods
it responds to). This goes clearly against the duck-typing
philosophy where a method should ignore the types of its
arguments - it should just use their methods and not worry.

OT ... but, the built-in classes of Ruby violate duck-typing
all over the place. You'll find lots of examples where:

1) methods have multiple functionalities based on the types of
the arguments (usually exact class not just respond_to?).

2) even where a method only has one functionality (or the
multiple functionalites are determined by means other than arg
type/capabilities - flags, number of args, etc), many/most
built-in methods can't take args that have the same
capabilities as what is excepted - they only take a certain
type or maybe one derived from it.

I think this sucks about the Ruby library - that most builtin
methods have poor polymorphism/duck-typing of their arguments.



=09
____________________________________________________
Start your day with Yahoo! - make it your home page=20
http://www.yahoo.com/r/hs=20
=20
 
S

Simon Strandgaard

In message "Re: [RCR] array or with non-array"
|Sometimes wish that [3, 5, 13] | [8] can be written as [3, 5, 13] | 8
|that ary |=3D 42 would be possible. [snip]
But I'm not sure this conversion is harmless and useful, or not. Let
us try for a while. Here's a patch to implement what you want. I
will merge it to the HEAD, to see how it goes.

Hehe.. that was fast. Thanks many times.
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: [RCR] array or with non-array"

|> But I'm not sure this conversion is harmless and useful, or not. Let
|> us try for a while. Here's a patch to implement what you want. I
|> will merge it to the HEAD, to see how it goes.
|
|Hehe.. that was fast. Thanks many times.

They are fragile. Don't assume they will behave same forever.

matz.
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: [RCR] array or with non-array"

|1) methods have multiple functionalities based on the types of
|the arguments (usually exact class not just respond_to?).

Usually using duck types, for example "to_str" for string-like
objects. It it's not, I consider it a bug.

|2) even where a method only has one functionality (or the
|multiple functionalites are determined by means other than arg
|type/capabilities - flags, number of args, etc), many/most
|built-in methods can't take args that have the same
|capabilities as what is excepted - they only take a certain
|type or maybe one derived from it.

Example, please?

matz.
 
E

Eric Mahurin

--- Yukihiro Matsumoto said:
Hi,
=20
In message "Re: [RCR] array or with non-array"
on Wed, 3 Aug 2005 07:34:27 +0900, Eric Mahurin
=20
|1) methods have multiple functionalities based on the types
of
|the arguments (usually exact class not just respond_to?).
=20
Usually using duck types, for example "to_str" for
string-like
objects. It it's not, I consider it a bug.

Having the the method take any object that implements the to_s
is good duck typing, but then we get right back to static
typing as soon the the built-in methods use the result of to_s
- they require it to be a string. Having many of the built-in
methods do a to_s is nothing more than a convenience (you could
easily do the same thing by putting a .to_s appended to those
arguments). It doesn't really help the arguments be more
polymorphic. If I had a class that implemented all of the
String methods, it wouldn't be any good to the built-in classes
- to_s would still have to return an actual String, not self.

But, this wasn't really what my #1 above was about. It was
about overloaded methods where the functionality is determined
by looking at the type of the arguments. One example would be
String#[arg]:

str[fixnum] =3D> fixnum or nil
str[range] =3D> new_str or nil
str[regexp] =3D> new_str or nil
str[other_str] =3D> new_str or nil

All of these behave very different. The way you figure out
what to do is based on type - which goes against the
duck-typing philosophy. I think the only advantage of
combining all of these functions into one method is
convenience. But, by doing so you loose the ability to handle
more general duck-typed/polymorphic arguments.

I think the []=3D method has a more legitimate excuse for the
amount of overloading - a syntactical one - because there is no
other way to make a method that can be assigned to and have
arguments (other than the rvalue). RCR #307 would help solve
that issue.
|2) even where a method only has one functionality (or the
|multiple functionalites are determined by means other than
arg
|type/capabilities - flags, number of args, etc), many/most
|built-in methods can't take args that have the same
|capabilities as what is excepted - they only take a certain
|type or maybe one derived from it.
=20
Example, please?
=20
matz.

I think a primary example where I would really like real
duck-typing in a built-in would be Regexp#match(str). This
requires the arg to be a String. I would really like to have
this be able to operate on a file. If I implement a class that
walks like, talks like, quacks like a String but really
accesses a file (practically did that in my rubyforge cursor
project), it wouldn't do any good because Regexp#match only
takes a String - period.

The Regexp#match method could be implemented to take ANY object
that implemented a some subset of the String API. Now you
might say that would be really slow, but you could just make
that functionality. Implementation-wise, you could special
case when the object in a String and do a much faster
implementation (but functionally the same as the general
version). A side effect of doing it this way is that you'd
have two implementations (with a String arg) that should be
functionally equivalent and thus great for testing (could be
put in a self-checking mode).

Eric



=09
____________________________________________________
Start your day with Yahoo! - make it your home page=20
http://www.yahoo.com/r/hs=20
=20
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: [RCR] array or with non-array"

|Having the the method take any object that implements the to_s
|is good duck typing, but then we get right back to static
|typing as soon the the built-in methods use the result of to_s
|- they require it to be a string.

I know but it is a matter of cost both efficiency and implementation.
Since current "restriction" covers 99.99% usage of strings, it is
kinda hard to pay cost to implement full polymorphic arguments like
you mentioned. When MetaRuby comes true, I'm not going to oppose,
perhaps.

|But, this wasn't really what my #1 above was about. It was
|about overloaded methods where the functionality is determined
|by looking at the type of the arguments. One example would be
|String#[arg]:
|
|str[fixnum] => fixnum or nil
|str[range] => new_str or nil
|str[regexp] => new_str or nil
|str[other_str] => new_str or nil
|
|All of these behave very different. The way you figure out
|what to do is based on type - which goes against the
|duck-typing philosophy. I think the only advantage of
|combining all of these functions into one method is
|convenience. But, by doing so you loose the ability to handle
|more general duck-typed/polymorphic arguments.

Convenience is important, sometimes more than pure duck typing.
There still be a room for improvement though.

|I think a primary example where I would really like real
|duck-typing in a built-in would be Regexp#match(str). This
|requires the arg to be a String.

Again, it's a matter of cost. For example, full duck typing
Regexp#match likely requires re-implementation of a regular expression
matching engine in Ruby.

matz.
 
D

Devin Mullins

Eric said:
Having the the method take any object that implements the to_s
is good duck typing, but then we get right back to static
typing as soon the the built-in methods use the result of to_s
- they require it to be a string.
Uhh... erh?
1. What methods do you think Regexp#match (or IO#write) calls on a
String object to extract the data out of it? What would you mock to make
your object quack like a String, for Regexp#match to be able to print it
to the screen? What would you have the #each method return?
2. What added flexibility would you get out of having to_str (not to_s)
return a duck rather than a String? Specifically, what flexibility would
you get that is not afforded by the ability to subclass String?

That said, I realize that not every core method is IO#write. :)
One example would be
String#[arg]:

All of these behave very different. The way you figure out
what to do is based on type - which goes against the
duck-typing philosophy.
True. But...
I think the only advantage of
combining all of these functions into one method is
convenience.
Convenience is very important. It's why Rubyists do:
array.each {|i| puts i}
but Javaers don't:
array.each(new Function() {
public void call(Object obj) {
System.out.println(obj);
}
}
(with a Function interface definition somewhere, and an each method
definition on a subclass of ArrayList somewhere else).

Devin
 
D

Devin Mullins

Devin said:
What would you mock to make your object quack like a String, for
Regexp#match to be able to print it to the screen?

Oops. Guess I should proofread.

Devin
 
D

David A. Black

Hi --

I think a primary example where I would really like real
duck-typing in a built-in would be Regexp#match(str). This
requires the arg to be a String. I would really like to have
this be able to operate on a file. If I implement a class that
walks like, talks like, quacks like a String but really
accesses a file (practically did that in my rubyforge cursor
project), it wouldn't do any good because Regexp#match only
takes a String - period.

You can define #to_str on your object to get Regexp#match to accept
it as an argument:

irb(main):006:0> o = Object.new
=> #<Object:0x401f3db4>
irb(main):007:0> def o.to_str; "hi"; end
=> nil
irb(main):008:0> /i/.match(o)
=> # said:
The Regexp#match method could be implemented to take ANY object
that implemented a some subset of the String API.

I think there's a semantic or perhaps definitional issue here, though.
What does it mean for a regular expression to "match" an arbitrary
object? I don't think it's just a matter of what methods the object
has. The object has to match the pattern, and the patterns are
descriptions of strings. I'm not sure how you would detect a pattern
like /[A-Z]{3}(\d\d)?/ in something that wasn't a string.


David
 
E

Eric Mahurin

--- "David A. Black said:
Hi --
=20
On Wed, 3 Aug 2005, Eric Mahurin wrote:
=20
=20
You can define #to_str on your object to get Regexp#match to
accept
it as an argument:
=20
irb(main):006:0> o =3D Object.new
=3D> #<Object:0x401f3db4>
irb(main):007:0> def o.to_str; "hi"; end
=3D> nil
irb(main):008:0> /i/.match(o)
=3D> #<MatchData:0x401eec60>

This doesn't really help in the polymorphism department. This
is no different than writing:

/i/.match(o.to_str)
The Regexp#match method could be implemented to take ANY object
that implemented a some subset of the String API.
=20
I think there's a semantic or perhaps definitional issue
here, though.
What does it mean for a regular expression to "match" an
arbitrary
object? I don't think it's just a matter of what methods the
object
has. The object has to match the pattern, and the patterns
are
descriptions of strings. I'm not sure how you would detect a
pattern
like /[A-Z]{3}(\d\d)?/ in something that wasn't a string.

By the same methods used in String. It could get away with
just one method to accomplish the task: #[positive_int]. We
could put this in IO for example:

class IO
def [](i)
self.pos =3D i
if eof? # pos can go beyond the eof
self.pos =3D i-1
return(nil) if eof?
self.pos =3D i
end
getc
end
end

If Regexp#match(obj) used just obj[pos], we could match a
Regexp across a file with the above.

Like I said earlier, for efficiency the code should special
case the String case and use the same implementation there is
now.



=09
____________________________________________________
Start your day with Yahoo! - make it your home page=20
http://www.yahoo.com/r/hs=20
=20
 
D

David A. Black

Hi --

This doesn't really help in the polymorphism department. This
is no different than writing:

/i/.match(o.to_str)

I think it's quite different, certainly in appearance and to some
extent in logic. I'm not sure how much more polymorphic one could
get, unless one had every object present its .to_s representation for
matching, which would not be good.
The Regexp#match method could be implemented to take ANY object
that implemented a some subset of the String API.

I think there's a semantic or perhaps definitional issue
here, though.
What does it mean for a regular expression to "match" an
arbitrary
object? I don't think it's just a matter of what methods the
object
has. The object has to match the pattern, and the patterns
are
descriptions of strings. I'm not sure how you would detect a
pattern
like /[A-Z]{3}(\d\d)?/ in something that wasn't a string.

By the same methods used in String. It could get away with
just one method to accomplish the task: #[positive_int]. We
could put this in IO for example:

class IO
def [](i)
self.pos = i
if eof? # pos can go beyond the eof
self.pos = i-1
return(nil) if eof?
self.pos = i
end
getc
end
end

If Regexp#match(obj) used just obj[pos], we could match a
Regexp across a file with the above.

scanf.rb does something along those lines. (It gets tricky with
scanf, because of whitespace and stuff, but it's basically position
and index manipulation.) Then again, scanf has always been
stream-oriented. I'm not sure I agree conceptually with the idea of
matching an IO object to a pattern. It actually feels to me like
there *should* be an explicit, intervening string representation.

Nor do I think this is a sign of failure or rejection of the principle
of duck typing or anything like that. Everything doesn't have to do
everything. For instance, you can't do File.rename on an integer, or
divide a hash by a float. And yes, I know that the reductio ad
absurdum is not proof of anything :) I just think there's some
nuance to some of the cases, including the specificity of the
pattern/string connection. I don't see pattern matching as strictly a
matter of integer indexability.


David
 
M

Michael Campbell

Simon Strandgaard said:
Sometimes wish that [3, 5, 13] | [8] can be written as [3, 5, 13] | 8
that ary |= 42 would be possible.

chris2 pointed out that it would be inconsistent with [1,2,3] + 4.
maybe let + append 4 to the array?



ary = [1, 3, 4]
#=> [1, 3, 4]

ary |= 2
#=> [1, 2, 3, 4]

Why not [2, 1, 3, 4] or [1, 3, 2, 4] or [1, 3, 4, 2] here? Arrays have
an ordering; how do you specify where your new element goes?
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: [RCR] array or with non-array"

|Why not [2, 1, 3, 4] or [1, 3, 2, 4] or [1, 3, 4, 2] here? Arrays have
|an ordering; how do you specify where your new element goes?

It's random. It uses Hash inside.

matz.
 
E

Eric Mahurin

--- Yukihiro Matsumoto said:
Hi,
=20
In message "Re: [RCR] array or with non-array"
on Wed, 3 Aug 2005 10:40:03 +0900, Eric Mahurin
=20
|Having the the method take any object that implements the
to_s
|is good duck typing, but then we get right back to static
|typing as soon the the built-in methods use the result of
to_s
|- they require it to be a string.
=20
I know but it is a matter of cost both efficiency and
implementation.
Since current "restriction" covers 99.99% usage of strings,
it is
kinda hard to pay cost to implement full polymorphic
arguments like
you mentioned. When MetaRuby comes true, I'm not going to
oppose,
perhaps.

Right now, it probably covers 100%. I think it is hard to
determine the usefulness of many features like this until it
they are implemented.
|But, this wasn't really what my #1 above was about. It was
|about overloaded methods where the functionality is
determined
|by looking at the type of the arguments. One example would
be
|String#[arg]:
|
|str[fixnum] =3D> fixnum or nil
|str[range] =3D> new_str or nil
|str[regexp] =3D> new_str or nil
|str[other_str] =3D> new_str or nil
|
|All of these behave very different. The way you figure out
|what to do is based on type - which goes against the
|duck-typing philosophy. I think the only advantage of
|combining all of these functions into one method is
|convenience. But, by doing so you loose the ability to
handle
|more general duck-typed/polymorphic arguments.
=20
Convenience is important, sometimes more than pure duck
typing.
There still be a room for improvement though.

I'm more of a purist and thus prefer the purity over the
convenience. And I know there may not be many in my camp.

As long as the built-in methods don't handle full
duck-typed/polymorphic arguments, the above overloading isn't
an issue. In the case above, all of the object types are
exclusive. I think cases where the object types aren't
exclusive or you have to prioritize is not a good thing. Those
cases lead to confusion and inconsistencies. An example would
be the overloading of Array#| you just added as a trial. With
this, you can now OR in any single element to the array EXCEPT
when that element is an Array. That exception case exists
because you can OR in a single element or an Array and the
Array case takes precedence. If you look at almost any
non-trivial bug in software, it happens when? exceptions and
end-cases. Putting intentional exceptions in the methods only
makes the problem worse - the caller now may have to handle
that same exception/end-case.
|I think a primary example where I would really like real
|duck-typing in a built-in would be Regexp#match(str). This
|requires the arg to be a String.
=20
Again, it's a matter of cost. For example, full duck typing
Regexp#match likely requires re-implementation of a regular
expression
matching engine in Ruby.
=20
matz.

It would definitely increase the code size. But, it shouldn't
change the run-time efficiency. Right now Regexp#match(str)
probably looks something like this:

raise(...) if !(String=3D=3D=3Dstr)
# code to match against a String

This would become

if String=3D=3D=3Dstr
# code to match against a String (functionally same as below)
else
# full duck-typed code using methods of str
end


Anyways, I'm glad I brought this up so that you can at least
give it some thought... Everybody talks about having your Ruby
code duck-typed, well why not ask the same of the built-in
methods?



=09
____________________________________________________
Start your day with Yahoo! - make it your home page=20
http://www.yahoo.com/r/hs=20
=20
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: [RCR] array or with non-array"

|> I know but it is a matter of cost both efficiency and implementation.
|> Since current "restriction" covers 99.99% usage of strings, it is
|> kinda hard to pay cost to implement full polymorphic arguments like
|> you mentioned.

|Right now, it probably covers 100%. I think it is hard to
|determine the usefulness of many features like this until it
|they are implemented.

But you need to convince its usefulness before someone implement it.

|> Convenience is important, sometimes more than pure duck typing.
|
|I'm more of a purist and thus prefer the purity over the
|convenience. And I know there may not be many in my camp.

I don't know about numbers, but a purist were not able to create Ruby.
He would create something very different from Ruby.

|It would definitely increase the code size. But, it shouldn't
|change the run-time efficiency.

I wasn't talking about performance cost. It was implementation cost.

matz.
 
C

Caleb Clausen

David said:
I'm not sure I agree conceptually with the idea of
matching an IO object to a pattern.=20

You need this to be able to do fancy parsing/lexing in ruby.
It actually feels to me like
there *should* be an explicit, intervening string representation.

And in this string would be what? The entire file contents? That works
well for small files, and I've done it many times myself. It doesn't
scale well, tho. If your explicit string contains only part of the
file, you get other problems.


Eric said:
If Regexp#match(obj) used just obj[pos], we could match a
Regexp across a file with the above.

Yes, and it would be orders of magnitude slower. This kind of thing is
the major performance issue in Cursor at the moment. Efficiency is a
tin god, but some attention needs be paid to it, to make sure that you
don't define interfaces that are inherently inefficent, for example.



Yukihiro said:
Again, it's a matter of cost. For example, full duck typing
Regexp#match likely requires re-implementation of a regular expression
matching engine in Ruby.

Not really, no. You can read into a buffer and match against the
buffer. This works pretty well for every pattern without anchors.
Supporting anchors too requires a smidge of rewriting the Regexp at
runtime. My current implementation interprets ^ and \A (or $ and \Z
when matching backward) as matching at the current file position,
rather than the beginning of file.

It's a minor pain, but I have most of the necessary code already.
There's a compromise or two that have to be made: an upper limit on
the length of a single match, ^ won't work right in some rarer cases
until regexp lookback in ruby 1.9. I don't like this, but these
restrictions seem minor enough, considering the massive increase in
functionality otherwise.


Hi --
=20


This doesn't really help in the polymorphism department. This
is no different than writing:

/i/.match(o.to_str)
=20
I think it's quite different, certainly in appearance and to some
extent in logic. I'm not sure how much more polymorphic one could
get, unless one had every object present its .to_s representation for
matching, which would not be good.
=20
The Regexp#match method could be implemented to take ANY
object
that implemented a some subset of the String API.

I think there's a semantic or perhaps definitional issue
here, though.
What does it mean for a regular expression to "match" an
arbitrary
object? I don't think it's just a matter of what methods the
object
has. The object has to match the pattern, and the patterns
are
descriptions of strings. I'm not sure how you would detect a
pattern
like /[A-Z]{3}(\d\d)?/ in something that wasn't a string.

By the same methods used in String. It could get away with
just one method to accomplish the task: #[positive_int]. We
could put this in IO for example:

class IO
def [](i)
self.pos =3D i
if eof? # pos can go beyond the eof
self.pos =3D i-1
return(nil) if eof?
self.pos =3D i
end
getc
end
end

If Regexp#match(obj) used just obj[pos], we could match a
Regexp across a file with the above.
=20
scanf.rb does something along those lines. (It gets tricky with
scanf, because of whitespace and stuff, but it's basically position
and index manipulation.) Then again, scanf has always been
stream-oriented. I'm not sure I agree conceptually with the idea of
matching an IO object to a pattern. It actually feels to me like
there *should* be an explicit, intervening string representation.
=20
Nor do I think this is a sign of failure or rejection of the principle
of duck typing or anything like that. Everything doesn't have to do
everything. For instance, you can't do File.rename on an integer, or
divide a hash by a float. And yes, I know that the reductio ad
absurdum is not proof of anything :) I just think there's some
nuance to some of the cases, including the specificity of the
pattern/string connection. I don't see pattern matching as strictly a
matter of integer indexability.
=20
=20
David
=20
--=20
David A. Black
(e-mail address removed)
=20
[/QUOTE]
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: array or with non-array"

|Yukihiro Matsumoto wrote:
|> Again, it's a matter of cost. For example, full duck typing
|> Regexp#match likely requires re-implementation of a regular expression
|> matching engine in Ruby.
|
|Not really, no. You can read into a buffer and match against the
|buffer. This works pretty well for every pattern without anchors.
|Supporting anchors too requires a smidge of rewriting the Regexp at
|runtime. My current implementation interprets ^ and \A (or $ and \Z
|when matching backward) as matching at the current file position,
|rather than the beginning of file.
|
|It's a minor pain, but I have most of the necessary code already.
|There's a compromise or two that have to be made: an upper limit on
|the length of a single match, ^ won't work right in some rarer cases
|until regexp lookback in ruby 1.9. I don't like this, but these
|restrictions seem minor enough, considering the massive increase in
|functionality otherwise.

It's good to hear it's not impossible. Although I'm not agree very
much about "massive" increase of functionality.

matz.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top