This is an archive of the accepted RCRs from Ruby Garden. This archive is being made available as part of the transition to the new RCR process and archive at .
Future accepted RCRs will be stored in sequence as an integral part of RCRchive.
Dir.chdir(new_dir) { # work in new_dir... }
I decided to declare them obsolete and give proper new names in the future (1.7 and forth coming 1.8/2.0). Do you have any idea of good name for them?
I'm not going to remove them, just give warning if you use them.--matz.
previously discussed - [] [] [] []
(0..4).to_a.partition {|e| e%2 == 0} # => [[0,2,4], [1,3]]Choices are:
This version allows multiple sets:
module Enumerable def partition result = {} each do |value| key = yield value result[key] = [] unless result.has_key?(key) result[key]
e.g.[-2,2,-1,1,0].partition { |x| x 0 }
yields{0=>[0], 1=>[2, 1], -1=>[-2, -1]}
class Array
def partition
result = {}
each do |value|
key = yield value
result[key] = [] unless result.has_key?(key)
result[key].push value
end
return result
end
end
p [-2,2,-1,1,0].partition { |x| x0 }
Which should yield something like:
{0=>[0], 1=>[2, 1], -1=>[-2, -1]}
The idea with the original function is, given a list and a predicate that judges true/false for each element, split a list into two lists, the first one containing all elements that satisfied the predicate, and the second one the others.
This example apparently creates a hash where each possible answer the function gives is a separate key, and all the elements that yielded the same answer are in an array located at that key.
This other example is cool and I'll definately add it to the library-of-useful-routines but IMHO I doubt that it is common enough to be part of the language.
The original idea might be a candidate though. Matz' suggested name "bisect" is quite nice I think.
/Gunnar
/Gunnar
In the passed block on the last line test there should have been the comparison operator. I'm trying now with HTML markup:
{ x <=> 0 }
foo = ['abc', 'def', 'gh', 'ij','klmn'] foo.partition {|s| s.length} #-> [ ["abc", "def"], ["gh", "ij"], ["klmn"] ]This has important benefits for processing and summarizing data files. Note that this would still accept a Boolean block, as a special case, satisfying the requirements you've all been discussing. The implementation of the method would be a little more difficult of course, but not terrible.
SysDep::signalList -> Array SysDep::can(:popen) -> true, false, or nil SysDep::MAX_OPEN_FILEIn the ::can case, false could mean partly available, and nil unavailable.
anException.exception => anException anException.exception("message") => anException.type.new("message")Proposal is to change behavior so that even with a message argument, #exception returns receiver (or clone), rather than a new object based on receiver's class. This would make it possible to propagate a specific Exception object (or clone) while specifying a message:
raise anException, "message" # currently raises new object; # with proposed change would raise anException or clone
But out of fairness, what about ? It certainly has a good name. Actually, I just took a look at it and it seems that it is very similar to RubyUnit. Maybe the authors of RubyUnit and Lapidary should join forces?
class TimeoutError <Interrupt endinstead of from StandardError. The change would make an exception raised at timeout to skip common "catch-all" rescue-clause. An example:
timeout(x) do # loop ensures we spend enough time in here loop do begin do_something rescue # rescues StandardError?, but should not # for example TimeoutError? end end endPreviously the example hangs, with above fix it won't.
begin .. rescue .. endto also capture TimeoutErrors.
d = Dir.new 'somedir' d.each do |fname| fullname = "#{d.path}/#{fname}" puts fullname end end
How would this be different from:
require 'find' Find.find('somedir') do |fname| fullname = File.expand_path(fname) puts fullname end
File.path
gives the pathname that you opened the file with, but File.expand_path
gives you an absolute path, which will get you to the file, but may not be what you want for display purposes.
What I really want is to be able to write:
class Dir def each_file(&block) entries.sort.each do |ent| fullname = "#{@path}/#{ent}" if File.file? fullname then File.open fullname, &block end end end end
Some of these may not be available on all platforms.
Methods for getting at and manipulating the mantissa and exponent would also be useful (like C99's frexp, ldexp, scalb, ilogb, modf).
class Float if m = (1..255).find {|i| (Math.ldexp(1,i)+0.5) % 1 == 0.0} MANT_DIG = m+1 EPSILON = 2.0**(-m) end end
All methods should return an object of the same type of the receiver, at least all String methods. Chaining String methods mixed with subclass methods would be easier to use. Here is the problem in short: ## in ruby 1.6.3 (2001-03-19) [i386-cygwin] class Foo <String end p h.upcase.type # -> Foo p h.reverse.type # -> String
the code got garbled, here is the (hopefully) correct version: ## in ruby 1.6.3 (2001-03-19) [i386-cygwin] class Foo < String end h = Foo.new 'bar' p h.upcase.type # -> Foo p h.reverse.type # -> String
Thank you very much for four understanding. Can you say in which version these changes will take effect? I would be very happy if as many as makes sense methods would return objects of the same type of the receiver. This makes them more predictable, easier to use, easier to chain; basically more fun ;) What about methods other than those by String? Also check Tobi
Hi There might be more methods of String where it would make sense to change them to return an object of the same type as the receiver:
To elaborate: suppose you want to add a few convenience methods to String or Array, or perhaps modify the behavior of Array to raise IndexError for out of bounds requests. You could do that by modifying String or Array directly, but that might lead to collisions and destroy other code, e.g. in the standard library.
So you implement your changes in a subclass of String, let's call it Str2. The problem is now that Str2#reverse and many other methods return a String. So you can't for example chain calls with these methods, because your Str2's turn into Strings. To fix this you have to reimplement all these methods in Str2. Or you have to create Str2 using a delegator pattern with method_missing, which means that it will no longer be a subclass of String. So is_a?(String) will fail, unless you override that too. In short, there are lots of problems.
Now, some of the methods in String, for example String#upcase return an object of the same type as the receiver, so Str2#upcase indeed gives you a Str2, without having to override it. If all methods behaved like this it would be much easier to create subclasses with different behavior.
Furthermore, the current implementation is a bit inconistent in that String#upcase and String#reverse behaves differently. In fact, String#reverse behaves differently depending on how many characters there are in the string:
Str2.new('a').reverse.type --> Str2 Str2.new('aa').reverse.type --> String
// Niklas
Also check for a list of String methods, and what they return. (there might be errors in my code) There might be many more methods where it would make sense to change their behaviour to return an object of the type of the receiver.
So why should the value returned by methods in class String be different?
f = Foo.new(gets)
Dave
"I agree the inconsistency in the current methods is not ideal." me too. "However, I'm not convinced that changing them to return a Foo in some circumstances (and not others) will help in any practical sense, and I worry it might weaken the language." Change *all*; then it's consistent, and strengthens the language. and perhaps more.
"I'm not convinced that changing them to return a Foo in some circumstances (and not others) will help in any practical sense, and I worry it might weaken the language." Yes. The original RCR reads: "All methods should return an object of the same type of the receiver, at least all String methods."
So why should the values returned by methods in class String be different?
Because String is the class that is subclassed, which makes it different.
I think that the main point is that many of the String methods are best understood as tranformations of the receiver and then it makes sense to make them return an object of the same type as the receiver -- it matches expectations better. For example, you wouldn't expect the #next of a Foo object to be a String. For methods which are not transformations of the current object, such as #+ I think it is fine to return a String. The line between transformations and non-transformations is a bit fuzzy, but any method that has a bang-equivalent is clearly a transformation.
Of course, this behavior can be implemented in the subclass -- but since all subclasses of String would have to implement this behavior for all the methods it would mean much duplicated work. Since it can be implemented in String that would be better, provided it does not affect performance.
Niklas
class Foo < String
def initialize(str)
super
@initial_value = str
end
att_reader :initial_value
end
What about the method 'chr' in 48.chr The receiver is a Fixnum and the result is a String. This is 'desired' behavior.
The solution is a bit more complex than just always :-)
class<<Module alias new0 new def new(&bl) r = new0 r.module_eval &bl if bl r end end
class Regexp def to_s r = inspect r[r.index("/")+1..r.rindex("/")-1] end endand it would be nice if Regexp#inspect always returned a valid regexp-literal, unlike for slash backslash slash slash (that i can't write here because of rubygarden's filter)
r == Regexp.new(r.to_s,r.options,r.lang)to be true for *every* possible regexp.
irb(main):014:0> RUBY_VERSION "1.6.5" irb(main):015:0> r = /foo/i /foo/i irb(main):016:0> r.to_s "#<Regexp:0x4026a8d0>" irb(main):017:0> r.inspect "/foo/i"
optparse
?getoptlong
before voting...class Foo def initialize(something) @instVar = something end end puts ((Foo.new('Hello-1')).inspect) #Result: <Foo:0x459a848 @instVar="Hello-1"> puts (Foo.new('Hello-2')).inspect #Result: <Foo:0x459a5f0>This was done with ruby version: 1.6.5 (2001-09-19) [i386-cygwin]
diff -u -r1.32 error.c
--- error.c 2001/10/03 07:19:10 1.32
+++ error.c 2001/10/23 07:40:57
@@ -323,10 +323,10 @@
if (argc == 0) return self;
if (argc == 1 && self == argv[0]) return self;
- exc = rb_obj_clone(self);
- rb_obj_call_init(exc, argc, argv);
+ StringValue(argv[0]);
+ rb_iv_set(self, "mesg", argv[0]);
- return exc;
+ return self;
}
static VALUE
a, b = "foo bar".match(/(f).*(b)/) p a, b # -> "f" "b"Returns upon match array of group items or 1 (true?) if no groups in regexp, returns nil if no match.
cf. []
Jim
We've just been through a round of this -- well, I guess technically it wasn't an RCR for String#match, but that possibility came up.
The business of capturing submatches with parentheses is very nice and convenient. But it isn't a "match", in the sense of a string matching a pattern.
To do this:
foo bar".match(/(f).*(b)/)without subsequently having access to the, ummm, match, doesn't make sense.
I'm not saying there isn't, conceivably, some new way of doing this lurking out there somewhere... but if there is to be a String#match, I don't think it should fail to return the match.
I meant
"foo bar".match(/(f).*(b)/)of course.
if (a, b = "foo bar".match(/(f).*(b)/)) # process a, b endIt can also be used like this:
if ("foo bar".match(/f.*b/)) # do something to recognize that it did match endSo, its a test for matching that returns true normally, but, as a side effect, returns an array if groups are present in the regexp.
Perhaps I'm just to used to being able to do this in perl that I don't want to give it up. If not String#match, then is there a better name for the method?
Here's the real scoop about why I'm so adamant about this: Ruby got rid of the perl construct of
$string =~ s,foo,bar,;With a much more elegant:
string.gsub!(/foo/, "bar");This puts the idea of the sub function as method of the string, not some odd thing that happens after the =~ operator.
string =~ /(foo).*(bar)/ ;Which then sets a bunch of $ variables in the old, perlish way that I want to avoid. It also does *not* return the group matches as an array like perl *does do*, meaning I have to mess around with $ variables, which I want to avoid.
In other words, I'm wanting some functionality of perl without it's syntax :->
The Regexp class almost does what I want, it just does more than I need in this situation. Generally, when I'm matching groups, I don't care about the full match ($&) , that's why I'm using groups.
Would you think it would be more appropriate to have String#match (or whatever) return the full matched expression if there are no groups? This would make String#match identical to the RCR proposal for String#[] wrt groups.
We could just have String#findGroups that returns the array of group matches:
if (a, b = "foo bar".findGroups(/(f).*(b)/)) ...and stay with =~ when there are no groups of interest
if ("foo bar" =~ /f.*b/) ...It just seems to me like we only need one method for both.
Personally I don't like the idea of a method that behaves differently based on whether there are capture parens in the regex.
So....
Maybe something like:
class String def capture(re) m = re.match(self) and m[1..-1] end end re = /(Hello).*(fray)/ str = "Hello, I'm a frayed knot." c = str.capture re p c # ["Hello", "fray"]
At any rate, I guess we can end this. It seems that a whopping two people find this important, so I'll let it go. It certainly isn't going to affect my deicision to use the language :->
I fail to see how my match method differs from =~[/you]
I would say it differs because when there's a match you then have to test whether it's returned 1 or an array. That could be a (minor) pain.
What's interesting is that I'm beginning to understand exactly why Matz designed MatchData the way he did :-) It gives you the whole match, plus the captures in array form. Doing this:
m,*g = re.match(str)is seeming less and less inconvenient all the time :-)
% cat x
re = /(Hello).*(fray)/
str = "Hello, I'm a frayed knot."
m,*g = re.match(str)
p m,g
% ruby x
#
[]
Surely this is not what you meant?
I was testing with 1.7.1:
dblack@laptop:~$ cat x re = /(Hello).*(fray)/ str = "Hello, I'm a frayed knot." m,*g = re.match(str) p m,g dblack@laptop:~$ ruby x "Hello, I'm a fray" ["Hello", "fray"]Hmmmm.... It's not there in 1.6.5.
But does this mean 1.7.1 has provided an easy enough way to do this? :-)
x = "abc" puts "Value of x: %p." % xWould print:
Value of x: "abc".This is more convenient than typing ".inspect". Plus, there are some other reasons why it is better to specify inspectness in the format rather than pre-evaluating inspectness in the argument. One is for specifying logging messages: the inspect string need not be computed if the logging message is suppressed.
Note: I used "%p" because it is the best I could come up with trying for a letter that is somewhat mnemonic -- reminiscent of our beloved "p" method (kind of far-fetched, but it's at least as good as "%g" for floating point :-). Too bad %i is already overloaded for integers!
abort("Data file is corrupted.")prints:
Data file is corrupted.and exits with exit value 1.
An optional extention to this RCR is to also provide an optional message argument in Kernel::exit (exit is just like abort but has the additional flexibility to specify exit values other than 1).
It actually would be an improvement to the RCR if abort with a message argument would store the message as the exception's string, and the default action for the SystemExit exception is to print the message to $stderr before terminating. That would seem to deal with at least part of your objection.
I don't see why you wouldn't just raise an Exception with the message yourself. The syntax is straightforward, and it's more clear to me reading a raise statement exactly which type of Exception I would need to rescue if I cared to do so. SystemExit isn't appropriate anyway if you're really trying to communicate some kind of error condition.
If you really mean to exit, then exit.
members()
), to list the values (values()
) and through Enumerable to list the indices with the values (each_with_index
). There seems to be no direct method to do
my_struct.each_with_member { |value, symbol| my_struct[symbol] = arbitrary_funtion(value) puts "#{symbol.id2name} is now #{value}" }Having
aStruct.each_pair {|sym,val| ... }
would do the job, I don't mind which order they come in. I think this would make code more readable and lighten the load for the programmer, which is the whole purpose of the Struct class.
I have made use of this feature in Perl to say [:alpha:] when I want word characters without digits and also without specifying ranges, which I believe are less cross-platform and less language-neutral than the POSIX class. GNU grep offers these also; they can be very convenient at times.
$ ruby -ve 'p 1000.0.to_s(), 1000.01.to_s()'
ruby 1.6.7 (2002-03-19) [i386-linux]
"1000.0"
"1000.01"
$ ruby -ve 'p 1.0000000001.to_s(), 1000000000.01.to_s()'
ruby 1.6.7 (2002-03-19) [i386-linux]
"1"
"1000000000"
$ ruby -e 'printf "%.18g ",10.000000001'
10.0000000010000001
Alternatively, it could be called IO#read_into(s).
inspect
method. This RCR would allow me to prevent recursion. If Method#==
was true when the method is the same method of the same instance, and Method#eql?
was true when it was the same method of an instance of the same class (i.e. broader) I could do this to prevent mutual recursion when doing inspect:
class Array def inspect history = Method.ancestors me = history.shift if history.detect {|x| x == me) # This is a self reference result = "Array #{self.id}n" else # We're examining some new # object result = "Array #{self.id} [n" self.each { |element| result += " #{element.inspect"}n" } result += "]n" end return result end endfor example. This would also help in [] I expect. The reason that
caller
doesn't satisfy my needs here is that it does not tell you which instance it is referring to, and using its information involves manipulating strings. I believe that this suggestion fits in with the philosophy of "eveything being an object".
mumble
in the preview pane, but will be correct when posted"I'd like to see the methods Object#instance_variable_get(name)
, Object#instance_variable_set(name, value)
and Object#instance_variable_defined?(name)
added to ruby. I've done this locally with the following ruby code:
class Object def instance_variable_get(name) eval("@#{name}") end def instance_variable_set(name, value) eval("@#{name} = value") end def instance_variable_defined?(name) # thanks to the poster for this suggestion. self.instance_variables.include?("@#{name}") end endbut I'm sure it could be done more efficiently from within ruby.
Therefore, I propose that the timeout method as a class method for class "Timeout".
# Based on 1.6.7 timeout code (untested) class Timeout def Timeout.timeout(sec, exception=TimeoutError) return yield if sec == nil begin x = Thread.current y = Thread.start { sleep sec x.raise exception, "execution expired" if x.alive? } yield sec ensure y.kill if y and y.alive? end end end
1) Timeout should be a module, not a class, since there's no good reason to ever instantiate a Timeout.
2) How do you propose I change my code so that it will work both with the new timeout class and with the old timeout method?
Agreed. I should have made it a module method.
As I understand it the parsing stage of GetoptLong can throw one of four errors:
begin GetoptLong.new().set_options( [ ... ] ).each ... rescue GetoptLong::Error printHelp() exit 1 endI seem to have to do something like:
begin GetoptLong.new().set_options( [ ... ] ).each ... rescue GetoptLong::AmbigousOption, GetoptLong::NeedlessArgument, GetoptLong::MissingArgument, GetoptLong::InvalidOption printHelp() exit 1 endThat feels a little clumsy. I wonder if there is some reasoning behind this or would it make sense to change GetoptLong so that there is a catch-all parent class for the errors that it can throw?
class Hash def |(h) clone.update h end endseems to work....
text = "All questions asked by five watch experts amazed the judge." m = /(w+) (w+)/.match text if m first, second = m.captures if first == "All" puts m.captures end endThis is nothing funky, but small things like this make source code more readable and beautiful IMHO.
~$ ri MatchData.to_a
This is a test 'ri'. Please report errors and omissions
on http://www.rubygarden.org/ruby?RIOnePointEight
--------------------------------------------------------- MatchData#to_a
mtch.to_a -> anArray
------------------------------------------------------------------------
Returns the array of matches.
m = /(.)(.)(d+)(d)/.match("THX1138.")
m.to_a #=> ["HX1138", "H", "X", "113", "8"]
Because to_a is called when exanding *variable, there's a useful
assignment shortcut for extracting matched fields. This is slightly
slower than accessing the fields directly (as an intermediate array
is generated).
all,f1,f2,f3 = */(.)(.)(d+)(d)/.match("THX1138.")
all #=> "HX1138"
f1 #=> "H"
f2 #=> "X"
f3 #=> "113"
I just came up with this by accident: It would be nice to have Range#step. Consider the following example:
0.step(360, 45) {|angle| puts angle }
Wouldn't it be nicer if we could do this like this in the standard Ruby?
(0..360).step(45) {|angle| puts angle }
undef_method :meth1, :meth2, :meth3
Comments
How about... (Dave, 2001-07-30 17:29:10)
What's wrong with the way Perl does it? (anonymous, 2001-07-31 16:00:47)
Unfortunately... (Dave, 2001-08-06 12:48:58)