From: Robert Dober Date: 2007-05-05T05:34:30+09:00 Subject: Re: RCR? On 5/4/07, Rick DeNatale wrote: > On 5/4/07, Joel VanderWerf wrote: > > > class String > > alias - delete > > end > > > > "foobar" - "oa" # => "fbr" > > > > Using an operator makes it abundantly clear that neither string is being > > modified. But then of course you don't get arity >= 2 version of delete. > > > > Was String#- being reserved for something else? > > The thing that vaguely bothers me about this definition of String#- is > that it doesn't seem ot have the same relationship with String#+ that > + and minus usually have. > > irb(main):002:0> class String > irb(main):003:1> alias - delete > irb(main):004:1> end > => nil > irb(main):005:0> "value1" + "value2" > => "value1value2" > irb(main):006:0> "value1" + "value2" - "value2" > => "1 > -- > Rick DeNatale > > My blog on Ruby > http://talklikeaduck.denhaven2.com/ > > That is a very valid point and makes me think about another inconsistency "acdb".delete("ab") would be "cd" while "acdb".delete(/ab/) would be "acdb"!! More I think about it more I believe that Logan hit a very sensible point. #delete(String) behaves as a hypotatical #delete([?c*]), this is a little bit vague, let me give an example "abcd".delete("ac") ---> "bd" why there is no "ac" in "abcd" "abcd".delete([?a, ?c]) --> "bd" of course!!! The same can be applied to #without. I feel that the following semantics would be pretty cool and consistent, but would it justify a Change Request? I will use PseufoRSpec synatx (s="abcd").delete("ab").is "cd" && s.is "abcd" (s="abcd").delete("ac").is "abcd" && s.is "abcd" (s="abcd").delete!("ab").is "cd" && s.is "cd" (s="abcd").delete!("ac").is "abcd" && s.is "abcd" For all Strings s and Strings t { s.delete(t).is s.delete(Regexp.escape(t)) s.delete!(t).is s.delete!(Regexp.escape(t)) s.delete_first(t).is s.delete_first(Regexp.escape(t)) s.delete_first!(t).is s.delete_first!(Regexp.escape(t)) s.delete_last(t).is s.delete_last(Regexp.escape(t)) s.delete_last!(t).is s.delete_last!(Regexp.escape(t)) } (s="abxab").delete(/ab/).is "x" && s.is "abxab" (s="ab").delete(/./).is.empty && s.is "ab" (s="ab").delete!(/./).is.empty && s.is.empty I guess that the semantics of delete_first* and delete_last* are pretty trivial, so I leave them out. Now for without "ab".without("ab").shall.raise ArgumentError # But maybe we shall be duckier here?(1) "ab".without!("ab").shall.raise ArgumentError# But maybe we shall be duckier here? "abcd".without(/./).shall.raise ArgumentError "abcd".without!(/./).shall.raise ArgumentError (s="abce").without([?a,?c]).is "be" && s.is "abce" (s="abce").without!([?a,?c]).is "be" && s.is "be" And eventually "abcd".to_a.is [?a,?b,?c,?d] "aba".to_a.is [?a, ?b, ?a] "abcd".to_set.is [?a, ?b].to_set Concerning (1): One could also imagine class String def without args args = args.to_set # but that invalidates some specs above # I have mixed feelings about this, it is "duckier" sure # but it exactly brings up what Rick has talked about, we are *not* applying #without to the string but to the characters of the string, better to make that crystal clear in the API. .... Hopefully someone still reads that whole lot ;) Cheers Robert Just for the fun let us imagine the following setup, sorry I am striving away from String#- to the original topic. But I do not consider the deviation of String#- off topic it is closely related. -- You see things; and you say Why? But I dream things that never were; and I say Why not? -- George Bernard Shaw