From: Maurizio De Santis on
Brian Candler wrote:
> What ruby are you using?

I'm using ruby 1.9.2dev (2010-07-11 revision 28613) [x86_64-linux] ,
maybe this is the reason...

David A. Black wrote:
> They are indeed the same method:
>
> rb_define_method(rb_cArray, "[]", rb_ary_aref, -1);
> rb_define_method(rb_cArray, "slice", rb_ary_aref, -1);
>

uhm... but if they are the same method, why aliasing the one, the other
does not become aliased? do I have to alias both methods?? and, if yes,
how??? :) I've tried, but with no success...
--
Posted via http://www.ruby-forum.com/.

From: David A. Black on
Hi --

On Sun, 1 Aug 2010, Maurizio De Santis wrote:

> Brian Candler wrote:
>> What ruby are you using?
>
> I'm using ruby 1.9.2dev (2010-07-11 revision 28613) [x86_64-linux] ,
> maybe this is the reason...
>
> David A. Black wrote:
>> They are indeed the same method:
>>
>> rb_define_method(rb_cArray, "[]", rb_ary_aref, -1);
>> rb_define_method(rb_cArray, "slice", rb_ary_aref, -1);
>>
>
> uhm... but if they are the same method, why aliasing the one, the other
> does not become aliased? do I have to alias both methods?? and, if yes,
> how??? :) I've tried, but with no success...

It's one underlying method (C function) with two Ruby names. If you
redefine one of the Ruby names you break the binding between that name
and the underlying method, and if you add an alias then there's a third
name. Each binding is separate; they don't automatically change
together.


David

--
David A. Black, Senior Developer, Cyrus Innovation Inc.

The Ruby training with Black/Brown/McAnally
Compleat Philadelphia, PA, October 1-2, 2010
Rubyist http://www.compleatrubyist.com

From: Maurizio De Santis on
David A. Black wrote:
>
> It's one underlying method (C function) with two Ruby names. If you
> redefine one of the Ruby names you break the binding between that name
> and the underlying method, and if you add an alias then there's a third
> name. Each binding is separate; they don't automatically change
> together.
>

uhhh I think I've understood: In order to do what I want to do, I should
implement something like this:


class Array

def slice_with_regexp(*args)
return self.select{ |val| val =~ args[0] } if args.size == 1 and
args[0].is_a?(Regexp)
# code that executes C function called by [] and slice
end

alias_method :slice_with_regexp, :slice
alias_method :slice_with_regexp, :[]

end


that is stupid 'cause breaks Array.slice performances.

Right?

Thanks a lot David!
--
Posted via http://www.ruby-forum.com/.

From: Intransition on


On Jul 31, 9:19 pm, Maurizio De Santis <desantis.mauri...(a)gmail.com>
wrote:
> Hello!
>
> suppose I want to modify Array.slice() (and consequentially, Array[]) in
> order to accept a RegExp as argument, and return values matching the
> regular expression. I tried to solve this problem in this way:

DON'T!

It's almost always a bad idea to override a built-in core method.
There are likely to be unintended effects that will break other code.
The best approach is to define a new method and use that.

From: David A. Black on
Hi --

On Sun, 1 Aug 2010, Maurizio De Santis wrote:

> David A. Black wrote:
>>
>> It's one underlying method (C function) with two Ruby names. If you
>> redefine one of the Ruby names you break the binding between that name
>> and the underlying method, and if you add an alias then there's a third
>> name. Each binding is separate; they don't automatically change
>> together.
>>
>
> uhhh I think I've understood: In order to do what I want to do, I should
> implement something like this:
>
>
> class Array
>
> def slice_with_regexp(*args)
> return self.select{ |val| val =~ args[0] } if args.size == 1 and
> args[0].is_a?(Regexp)
> # code that executes C function called by [] and slice
> end
>
> alias_method :slice_with_regexp, :slice
> alias_method :slice_with_regexp, :[]
>
> end
>
>
> that is stupid 'cause breaks Array.slice performances.
>
> Right?
>
> Thanks a lot David!

I should add that my full advice is to avoid overriding slice and/or []
globally. A better way to alter core functionality is on a per-object
basis:

module ExtendedSlicer
def slice(*args)
arg0 = args[0]
case arg0
when Regexp
grep(arg0)
else
super
end
end
end

a = %w{ one two three four }.extend(ExtendedSlicer)
a.slice(0,2) # ["one", "two"]
a.slice(/o/) # ["one", "two", "four"]

The main advantage here is that it's a better fit: you need an object to
behave a certain way, and you teach that object to behave that way.
Another advantage is that it makes you work a little harder, and
therefore helps you evaluate more carefully whether or not you need to
perform the modification at all.


David

--
David A. Black, Senior Developer, Cyrus Innovation Inc.

The Ruby training with Black/Brown/McAnally
Compleat Philadelphia, PA, October 1-2, 2010
Rubyist http://www.compleatrubyist.com