This is an archive of the rejected RCRs from Ruby Garden. This archive is being made available as part of the transition to the new RCR process and archive at .
Future rejected RCRs will be stored in sequence as an integral part of RCRchive.
class Msg def initialize(name, type, txt) @name, @type, @txt = name, type, txt end # ... endSo, could we change parameter passing slightly so that if an instance method has a formal parameter starting with an '@' sign, the incoming value is assigned directly to the corresponding instance variable? Using this scheme I could write the above as:
class Msg def initialize(@name, @type, @txt) end end
class Proc def *(other) raise unless arity == other.arity proc {|*a| self.call(other.call(*a))} end endand then, as a side-note being able to do:
f = lambda{|x| 2*x} g = lambda{|x| x+1} h = f * g h.call 1 # => 4Why not throw in some syntactic sugar for the "lambda{|x| ...}" stuff à la Haskells "x -> 2*x" while we're at it!
Too vague; no actual mechanism proposed.
I think the poster may be talking about methods with implicit receivers. In that case you have more information on the methods it may call or not; but the poster doesn't take care of (or even mention) Object#method_missing, method-undef, forward references, and how his feature would interact with those.
I don't know what Perl's strict-subs have to do with it, I don't remember anything it did for me, and IIRC, strict-subs don't do anything when using Perl's method-lookup.
"hello #fred and barney"
With respect, you should think again. W3C wants XML to replace HTML, M$ is using XML as its data protocol in .NET, MacOSX uses XML for its config files. Beyond that all sorts of publishers and data providers are moving to XML or (XML compliant SGML) for preparation, tracking and publication. All the signs are that XML is going to be the data format (and markup language) of the 2000s-10s.
Where I work we have had to begin dealing with information being delivered in XML. Although its a perl shop, I have pursuaded the manager to let me use python for 'prototype development purposes'. Although I prefer ruby, the excellent XML support in python made the case for python arguable.
Absolutely! And what this means is that ruby must have acess to some parser, perhaps expat (but why not Xerces?), but most importantly of all the standard APIs (ie SAX and DOM) will need to be supported (though there is nothing wrong with having some unique ruby-xml API in addition the the standard ones).
<tag1 foo="bar">
<tag2 this="that"/>
<tag2 this="the other">mydata</tag2>
</tag1>
becomes:xmle.element_tag -> tag1
xmle.attr_foo -> bar
xmle.tag2[0].attr_this -> that
xmle.tag2[1].element_data -> mydata
xmle.tag2.count -> 2
xmle.tag2.each {|element| puts element.element_data} -> nil, mydata
Notice I preface the attributes of a tag with attr_ and the sub-tags with the actual name. The array index (tag[0]) is optional if there is only one. The xml element's direct data is element_data. Its worth trying to build this into some type of library to deal with XML that's Ruby flavored.
What we should to is not to waste time using expat at all. We should use a professional quality XML parser. IMHO this should be Xerces (from xml.apache.org) because of MSXML's platform specificity and 'extensions' to the standard.
The approach taken with Perl, to create Xerces.pm, an API to Xerces-C (resulting in much faster parsing), would seem to be the obvious way to go.
Math::PI.times { puts "Hello" }
Complex::I.times { puts "Goodbye" }
%q{nesting {really} works}
") and make the parser really just return literally what is written.
Maybe omit the detection of nested parenthesis that is possible in the other %-notations too
("%q{nesting {really} works}") and make the parser really just return literally what is written.
After seeing a million examples of overriding methods in classes by aliasing an existing method to something with a more obscure name, defining over that method and then calling the alias of the old method in the new method's code, I convinced myself there HAD to be a better way. In that vein, I've implemented the ability to "attach" an anonymous variable to a given method.
It works like this:
module MyStringComparison def self.enabled String.class_eval <<-'END' old = instance_method(:<=>) def <=>(other) c1, c2 = [self, other].collect {|s| s.gsub(/[^[:alnum:]]*/, '').upcase } method_var.bind(c1).call(c2) end define_method_var(:<=>, old) END begin yield ensure String.class_eval <<-'END' define_method(:<=>, method_var(:<=>)) END end end end irb(main):003:0> "Abc...?" <=> "A B C!" 1 irb(main):004:0> MyStringComparison::enabled {"Abc...?" <=> "A B C!"} 0 irb(main):005:0> "Abc...?" <=> "A B C!" 1
As you can see, not only does it leave the String class unchanged, it also does not provide any visible evidence of the : method being overridden, and the method overriding can be recursed without worrying about how exactly to do aliasing, defing, and undefing without conflicting upon names for old method storage.
Pretty simple and generalized, eh? :) You could essentially attach any variable you would like to a method in this fashion, but it's most useful for keeping an "anonymous" copy of the old method around. The implementation I came up with can be found .
Regarding the technical aspect of the proposed change, it increases the size of a NODE by one pointer, as well as the size of a FRAME. It shouldn't add any significant amount of overhead because of this, and remain invisible on benchmarks.
I'm not sure I have the hang of what the advantage would be of this over the aliasing approach. It seems to involve at least as many steps. I don't (yet) see why this way would be any easier, or make things easier to keep track of. Can you elaborate a little on that?
I don't think method_var covers exactly the same "problem space" as Ruby Behaviors, but there are certainly some points of contact, so perhaps some comparative remarks would be in order. With Behaviors, having to alias and unalias isn't an issue because the aliasing and unaliasing are done automatically. You design a Behavior, (such as one which redefines ), and the underlying engine takes care of swapping it in and out. Then in your top level code you invoke the behavior in a block.
For what it's worth, here's what you'd have to do to get a Ruby Behavior that did your string method change. ("ship" is the default alias for the spaceship operator :-)
module Behaviors class Behavior class BriansThing ", (other) c1, c2 = [self, other].collect {|s| s.gsub(/[^[:alnum:]]*/, '').upcase } c1.ship(c2) end EOS ) end end end end # Test include Behaviors b = Behavior.new(:BriansThing) s = "Abc...?" t = "A B C!" p s t # => 1 b.adopt { p s t } # => 0 p s t # => 1Anyway -- I'm not sure how to the point this is, but note that you get that same effect of a temporary change (but not without possible dangers... but that's another story), without having to explicitly save and restore, since the underlying Behavior engine does that for you.
That should be:
p s t # => 1 b.adopt { p s t } # => 0 p s t # => 1
Solution only allows to bind one var to the method.
Can be fixed if everyone agrees not to set method_var directly, and that method_var is a pointer to the Method object representing that Method. Then you can add accessors to the Method, as you can do with Class objects.
It would work better if Methods were made more like "real objects"; that is, if there a 1-to-1 identity correspondence so that when you query for a specific method, you get always the *same* object. It would remove most of the nastiness associable with the solution I propose.
[]= is bang; so a version of []= that doesn't modify the receiver would be cool. 1.1. Array#set_at position, new_value an_array.set_at(2, new_value) and maybe 1.2. Array#set_at! or 1.3. an_array.at(2) = new_value # for example "add a newline to the second and last item in the array" an_array.each_index do |x| new_val = an_array.at(x) + "n" if (x == 2) or (x == (an_array.size - 1)) an_array.set_at(x,new_val) end end or even: an_array.each_index do |index,item| or an_array.collect |index,item| if (index == 2) or (index == (an_array.size - 1)) item + "n" else item end end
These for example are describing examples of collect and collect! in the Pickaxe Library Reference: collect a = ["a", "b", "c"] a.collect {|x| x + "!" } -> ["a!", "b!", "c!"] a -> ["a", "b", "c"] collect! a = ["a", "b", "c"] a.collect! {|x| x + "!" } -> ["a!", "b!", "c!"] a -> ["a!", "b!", "c!"] The following is what I want to have as an additional, new method for Arrays (for ease of use, convenience, and nicer code): set_at a = ["a", "b", "c"] a.set_at 0,"x" -> ["x", "b", "c"] a -> ["a", "b", "c"] set_at! a = ["a", "b", "c"] a.set_at! 0,"x" -> ["x", "b", "c"] a -> ["x", "b", "c"] Tobi
As per my ruby-talk postings, I'm not sold on this. But in any case, I'd think a different name would be better. 'set', in any form, suggests that the receiver is going to set something.
Maybe: a = [1,2,3] a.with_at(0,100) => [100,2,3]
The code should not be all run together:
a = [1,2,3] a.with_at(0,100) # => [100,2,3]
David
Great! Thanks for your suggestion. My whish is to have that functionality for arrays; the name of the method is open for discussion. with_at position,new_value with_at! position, new_value or: (all with bang and non-bang versions): fill_at, place_at, value_at, at()=, at()!=, replace, set_at, ...
sorry, one in the listed doesn't make sense: at()!= maybe: at()= and at()=!
> an_array.each_index do |x| > new_val = an_array.at(x) + "n" > if (x == 2) or (x == (an_array.size - 1)) > an_array.set_at(x,new_val) > end > endWhat's wrong with the following?
an_array.dup.each_index do |x| an_array[x] += "n" if (x == 2) or (x == an_array.size - 1) endSorry, but I think that set_at or with_at would not be used that often to add it to the libs.
a.with_at(pos, val)would equal to
(b = a.dup)[pos] = val; bcorrect?
What I'd like to have is a collect_index or something alike. For me this would be much more useful, because it would let me ommit a counter variable.
Regards, Michael
> What's wrong with the following? > an_array.dup.each_index do |x| > an_array[x] += "n" if (x == 2) or (x == an_array.size - 1) > endOnly that the dup doesn't do anything :-) But Tobi's example seems to throw away the results of set_at, so it ends up as a no-op. Which doesn't in itself mean too much, but I still think that this isn't needed in the core language.
> a.with_at(pos, val) > > would equal to > > > (b = a.dup)[pos] = val; b > > correct?Yes.
> What I'd like to have is a collect_index or something > alike. For me this would be much > more useful, because it would let me ommit a counter > variable.I'd like that too -- so much so that I wrote it a few months ago :-)
module Enumerable def map_with_indices res = [] each_with_index do |e,i| res.push yield e,i end res end end
map_with_indices would be a great addition to Ruby. (just hours ago I thought that collect_with_index would be cool; but I like your choice for the name much more) It should be available for arrays etc. and perhaps both bang and non-bang versions would make sense. Maybe you want to consider posting a new RCR for that?
... I still want a non-bang version of []=, which could look something like set_at(new_value, position) or with_at(new_value, position) (= this RCR is not obsolete; map_with_indices is a seperate request)
> What do you guys think?
I don't think Ruby core changes should be vote-based -- nor do I think they are likely to be :-) I tend to see it more as: people might use and exchange ideas, and based on their experience (qualitative and quantitative) decide whether an RCR is a good idea. Behaviors definitely have the potential to play a role in this, and to divert some of the RCR traffic.
I happen to think that map_with_indices actually should be a method of Enumerable, based on my own wanting to have it and talking with other people about it. Meanwhile I've got my own Behavior-friendly version :-)
map_with_indices map_with_indices!This could be added to Enumerable, and made available for arrays (etc.) I believe it would be a very handy method, that adds to Ruby's readability, conciseness and elegance. For example, it would obsolete the need for counters in certain operations.
res = [] ary.each_with_index {|e,i| res.push "#{i}: #{e}"}you could do:
res = ary.map_with_index{...}Dinky example, but I think it's a very useful method.
Also it would add symmetry to Enumerable. Though actually to be fully symmetrical (or whatever), we'd also need map_indices, which would be the map equivalent of each_index. (instead of (0...ary.size).map {|n|...})
Here's a running example, using an implementation of map_with_indices by David Black: #################### # by David Black: module Enumerable def map_with_indices! res = [] each_with_index do |e,i| res.push yield e,i end replace res end def map_with_indices dup.map_with_indices! end end #################### a1 = ['zero','one','two','three'] a2 = ['zero','one','two','three','four','five'] # add a newline to the second and last element of any array def my_format a new_a = a.map_with_indices do |element,index| if (index == 1) or (index == (a.size - 1)) element + " " else element end end end a1_formatted = my_format a1 a2_formatted = my_format a2 p a1_formatted # -> ["zero", "one ", "two", "three "] p a2_formatted # -> ["zero", "one ", "two", "three", "four", "five "] Tobi
class Foo def bar puts "bar" end # Make bar visible only to MyClass export :bar, MyClass end
Could your database example be solved with the following code:
private def foo puts "foo!" end public def bar return self.method(:foo) end end f = Foo.new b = f.bar b.call
class A feature { ANY } -- Visible to all value_of(other: A): INTEGER is -- What is other's value? do Result := other.value end -- value_of feature { A } -- Visible only to A value: INTEGER end -- class AThis is highly trivial, but it should give a fair idea of what can be achieved with such a mechanism. Here we basically give access to 'value' only to other objects of type 'A'. This cannot be accomplished using the protected/private/public approach.
I did not mean to imply that any object should be allowed to invoke bar() and get a reference to the private method foo. In a more realistic situation, bar() could check who the caller is (perhaps by requiring the caller to pass its binding as a parameter, then evaluating "self.type", or perhaps by passing in a key that only the calling class could possibly know). The reason for doing this in bar() instead of in foo() is because it is probably not a cheap operation, and so doing it only once is desirable.
The obvious disadvantage with this method is that it is not as clean as a real "export" feature.
Also, how do you propose to do the type checking? Since classes in Ruby are very dynamic, what is to stop someone from doing this:
class Database # repoen the Database class def foo(databse_object) database_object.exported_method() end end
There are a lot of places in Ruby where access control could certainly be done better, and other places where it is just plain broken. (I think this is the former case). So here's a question to whomever is reading: what can/should be done about the more general problem of fixing access control in Ruby?
useful.Array.new([1,2]) => [1,2]
Symbol.new should replace String#intern; the latter would only be kept for backwards compatibility.
Class.new and Module.new, when called with a block, should also call #module_eval with that block.
change Regexp#to_s so that it returns a string that gives back the first argument to Regexp.new (or equivalent).
add Regexp#options and Regexp#lang, which gives back Regexp.new's 2nd and 3rd arguments.
Given:
1 < x < 5
If 1<x is false, then what does it mean to have:
false < 5
If this is guarantee to be false, then would:
false>= 5always be true? In that case, what happens with:
1>= x>= 5if 1>=x is false?
I think making this change introduces a lot of problems, and the "C way" of writing such expressions is not too terribly difficult to read.
BTW, Rubygarden's translation of &lt; and &gt; into < and > makes it difficult to type messages like this.
false because it would short-circuit at the first failure, much like
(1 already does.
I asked about this on the mailing list once, and was referred to matju's Hollow* classes (in the MetaRuby package). Unfortunately, they enforce some constraints on their implementation that are inconsistant with the built-in Array and Hash classes.
keys()
defined would give you similar leverage to have each()
defined. Modules Enumerable
and Keyable
, perhaps?.
[1,2].map(:succ) #=> [2,3]I know that you can do it with
[1,2].map {|e| e.succ}but its more than a "shortcut". IMHO its more in line with how map is used in functional programming languages. I we want to be really fancy we could also allow methods as parameters. But maybe that's taking it too far. I'm not sure what should happen if one both gives a parameter and a block. Either skip the parameter or apply it first? Probably the latter since you would otherwise not specify the parameter. So here's the new semantics I'm asking for (I'm not sure about the extra args but added them anyway):
class Array def rcr50_map(symbol = nil, *args, &block) if symbol.kind_of?(Symbol) a = self.map {|e| e.send(symbol, *args)} else a = self end a.map(&block) end endOh, it should really be Enumerable#map but this is just an example!?
Just a suggestion for an alternative method name:
[1,2].map_with(:succ) #=> [2,3]
[1,2].map(:succ) #=> [2,3]I'd write
[1,2].map(&:succ) #=> [2,3]Of course this would require a parser change and I doubt it will be done, but it would have two advantages:
[1,2].map(&:+, 4) #=> [5,6]
apply
?
class String def upcased? if self.upcase == self return true else return false end end def downcased? if self.downcase == self return true else return false end end def capitalized? if self.capitalize == self return true else return false end end end
class String
def upcased?
self.upcase == self
end
def downcased?
self.downcase == self
end
def capitalized?
self.capitalize == self
end
end
attr_initializer :foo, :bar
This can be done by adding it as a method to Module, just like attr_accessor and similar methods.
class X
attr_initializer :foo, :doo, :bar
...
end
basically expands to:
class X
def initialize(foo, doo, bar)
@foo, @doo, @bar = foo, doo, bar
end
...
end
( More info in [] )
class X def initialize(@foo, @doo, bla, @bar) @bla=bla.to_f end endThis would be same as:
class X def initialize(foo, doo, bla, bar) @foo=foo; @doo=doo; @bar=bar @bla=bla.to_f end endand this has benefit of having standard initialize too.
class X def initialize(@foo, @doo, bla, @bar) @bla=bla.to_f end endI just don't think that looks good or is easily understandable. It uses two different styles/mechanisms to do the initialization.
However, some argue that you should be able to do (for any method, not only initialize): def anymethod(@foo) and then have the instance_variable @foo be assigned directly, simply because it is consistent with blocks as in { |@foo| ... } I can sympathize with that but I think it's a different issue. I also don't find the initializer written as above particularly clear and wouldn't like to write them that way. In that case I prefer writing out an intitialize like it is today. It just doesn't resonate with me, but of course people have different tastes.
To the second poster, I don't agree that a shortcut must be fully flexible. attr_initializer should surely not take a block, just like attr_accessor does not! If you need that, instead use the standard method.
Consider that also attr_accessor, attr_reader, attr_writer are shortcuts for a common case and therefore they are useful, but there are still times when you need to define your own accessor methods too, like if you want to put constraints on the values, do bounds checking, or to let the getter return a different type than you use internally. In all these cases you fall back to the standard method and the case is the same here. It is clear attr_initializer does not, for example, allow you to add default values. It's not meant to solve every case.
Let's make one thing clear, a shortcut like this, also attr_accessor, is not meant to replace but to extend. It allows you to define the function manually if you want or when you need to.
Consider most other RCRs that suggest to add a fairly specialized method to some class just for completeness, and people often seem to think that's a good idea. But additions should be made only for commonly used things. For me, the above initialize is very common for simpler container-type classes. For others I need to use a full def initialize(). I think RCRs should be rejected if they are not common enough, to avoid growing the language too much, and you are free to do so if you wish.
But you find attr_accessor useful, don't you? Then attr_initializer could be useful too. But not for everyone perhaps. It's just a suggestion and you need to decide if it is worthwhile for you or not. Whether to allow def meth(@var) or not is another question. In fact, I would still find attr_initializer useful regardless. To all readers - if you are reading RCRs, please vote, even if you specify that you don't really care.
The idea is: allow a second argument to Dir.glob (aka Dir.[]), that argument being used as a filter, passing everything returned by the glob through Kernel#test.
Example: Dir.glob("*.rb", "f") (returns all *.rb that match test("f", name)) Implementation:
class << Dir alias :oldglob :glob def glob(g,t=nil) d = oldglob(g) if t d.find_all {|e| test(t,e)} else d end end end
(P.S. There seem to be extra blank lines being put in here but I'm not using Opera this time :-)
s = "a foo and a bar" re = /a (f.*?o) and a (b.*?r) to/ foo, bar = s[re] puts foo,bar # -> foo bar
As a side note, I think your regex is a bit messed up (since f.*?o matches "fo", then none of the rest of the regex matches; I'm not sure where the "to" part is supposed to fit in).
a, b = foo.match(/(bar).*(baz)/)
No one showed much interest. I like either of s[re] or s.match(re) better than:
dummy, a, b = /(bar).*(baz)/.match(foo).to_a
or
a, b = [ $1, $2 ] if foo =~ /(bar).*(baz)/
Actually, I think I may like yours better, fewer characters :->
---------------------------------------------------------------------- | Jim Hranicky, Senior SysAdmin UF/CISE Department | | E314D CSE Building Phone (352) 392-1499 | | jfh@cise.ufl.edu http://www.cise.ufl.edu/~jfh | ----------------------------------------------------------------------
a, b = foo.match(/(bar).*(baz)/)"is a generalization of the existing mechanism", because the existing mechanism is that match returns a MatchData object.
I don't think it's so bad to do:
a,b = /(hel).*(ere)/.match("hello there")[1..-1](note: no "to_a")
It changes functionality. Presently, this is what happens:
irb(main):001:0> s = "foo and bar" "foo and bar" irb(main):002:0> s[/(foo).*(bar)/] "foo and bar"
If I understand correctly, then this is what you suggest:
irb(main):001:0> s = "foo and bar" "foo and bar" irb(main):002:0> s[/(foo).*(bar)/] [ "foo", "bar" ]
Why would the String#[] return an string in almost all cases, but an array of strings in one oddball case? (Yes, I know that aString[aFixnum] -> aFixnum is already an exception).
BTW, could someone please fix the HTML filter to not change &gt; to > when I click "preview"?
After all, POLS and HOOP are the main
philosophies driving Ruby, if I'm not
mistaken, and having String#match feels
to me to be less suprising and more human
oriented than not having it, especially
when there's a String#gsub.
It seems I'm in the minority, though.
For example:
str = "I say: Hello there to you" re = /(Hel).*?(ere)/ str[re] # => "Hello there"would have to be rewritten in a less concise manner.
Every method that used String#[] with, say, a regex passed in as an argument, would now have to examine the regex, and/or branch on the type of the return value of [], etc....
I agree that having to examine MatchData objects can be a bit cumbersome. But in a sense you're suggesting that a similar examination process be conducted on the return value of String#[], instead of on a MatchData object -- plus introducing an inconsistency in the method's behavior.
float x = 3/2;
printf("%fn", x);
puts 3.0/2.0
So what? C is a low level language...
C being low-level and Ruby being high-level isn't the issue. Ruby is dynamically typed, and it's perfectly legal for you to pass integers into a function that is expecting floats. Adding an integer division operator does not solve this problem.
Incidentally, Ruby is written in C, and Ruby extensions are written in C. That's not an insignificant argument for maintaining some coherence between the two languages.
...but if x and y happened to not become Float in the preceding code, you get a bogus answer.
This is definitely a problem with dynamically-typed languages, and extends far beyond just division. If I have a function that expects a String and I pass it an Array, then what should that function do? Note that C++ has a similar problem with templates:
template<typename T, typename U> float foo(T t, U u) { return t / u; } ... std::cout << foo(3, 2) << std::endl;
Should we remove binary - since we can just combine binary + and unary - instead? Maybe += needlessly complicates the language as well.
The operators you mentioned do not carry type information with them. An integer division operator and a floating-point division operator both carry type information. That is why they seem to not match Ruby philosophy.
>4) I suspect that for the work you are doing, Ruby is probably not the right solution for the job. A language better suited to floating-point calculations will probably perform much better (i.e. be faster and more accurate).
Is that because you assume that I want to type 2/3 at my program? I'm extracting certan features from XML files and calculating the probability of finding certain features in future files...
No, I'm suggesting that you use a different language, because:
...I have a lot of
prob = feature_count / total.to_f
So why not convert your data to floats when you read them in from your xml file? That seems to me to be the simplest solution.
If you really want Fixnum#/ to do floating-point division in spite of all this, then one of the beautiful things about Ruby is that you CAN make this happen:
class Fixnum def /(other) p self p other end end 3 / 2 # will print 3, then 2, then return nilIn order to keep this from interfering with Ruby code that you didn't write, you may want to consider using something like Ruby Behaviors to limit the scope of the change.
C being low-level and Ruby being high-level isn't the issue.
I think it is. A high-level language ought to allow me to think about numbers instead of int, long, float, double. Saying that it shouldn't do that is in my opinion equivalent to saying it shouldn't have lists. Out in the world, when I divide two of those things called `numbers', I sometimes get a result with a decimal point in it. I don't care whether the `numbers' already had decimal points in them or not.
So why not convert your data to floats when you read them in from your xml file?
A perfectly reasonable question, except that I'm not reading values from the XML, I'm counting the occurance of certain values. Although as I said, this particular program is irrelavent (for one thing it is already written and running), it long ago occurred to me that I could just initialize values to float, like:
feature_count = 0.0 [...] feature_count += 1 if feature(doc) [...] prob = feature_count / totalbut think for a second what that conveys to someone reading the code. Why am I doing that? Since the value is a count, perhaps they should change it to
0
to improve efficiency. Or maybe I should mark my code with comments like:
# Don't change this or else Ruby will # do integer division later on. x = 0.0As ugly as I think using
.to_f
is, at least it puts the explicit conversion with the division instead of some random amount of code before it.
In a final attempt to be clear, I don't have any major problem with telling Ruby what I mean using .to_f
, I'm concerned with telling humans what I mean. Which is why I want to use Ruby in the first place. And when I say ``want to use'', I mean in general. The specific program in question has long-since been written with copious and ugly .to_f
's.
Ruby is an interpreted language, and is slower than an equivalent solution in a compiled language.
Ruby isn't just a slower language, from the language shootout it appears to be just about the slowest language. If that was my primary concern, I wouldn't be using it.
A Ruby solution for a program that must process large amounts of data will probably have many pieces implemented as a C extension in order to be efficient.
Lucky me, an interface to a fast XML parser is already there. You might want to look up REXMLBuilder for your own reference.
If you really want Fixnum#/ to do floating-point division in spite of all this, then one of the beautiful things about Ruby is that you CAN make this happen:
I don't claim to be a Ruby expert, but I have been using it for some time now, have prototyped a simple fulltext search engine and Bayesian classifier in it (calculating probabilities, get it?) and I think you can assume I'm familiar with the simplest concepts of the language which you chose to demonstrate. I don't do what you suggest because that is even worse for people reading the code.
Meanwhile, nobody has mentioned why it is so important to have integer division as the default. The closest you've come is to say that it's not an insignificant argument to say Ruby should be like C. Yet you seem to be so opposed to it that you'd rather I use a different language than advocate that Ruby compute a floating point value when dividing integers. So what exactly is the problem with:
3 / 2 #=> 1.5 (3 / 2).to_i #=> 1? Do you have a language-design argument for why this would be undesireable? Does it go something like ``but, well, the arguments are integers''? Should I then count for you the number of built-in methods that return a type different from their arguments?
It's even easy to implement without much overhead, since Ruby already calculates the remainder when it sees 3/2
only to throw it away later. If the remainer is 0, return, otherwise redo as a floating point divide.
My argument is that this way conveys more information and is more clear to humans reading the code than any method you care to name for guaranteeing floating point division using the current semantics. If you do manage to name a method that is equally informative and clear, I'll gladly use it.
You also haven't answered my question about 2 / 3.0
. Is your only argument for why this should be a floating point division that C does it that way? It sure looks equally like an integer division to me.
x/y
, they know which kind of division they want. I can't think of any algorithm that would require dynamic selection of the division operator. If fact, if you can't guarantee the type of x and y, then every time you divide, you must write either
I suspect there is a lot of code out there that inappropriately assumes it always gets integers when doing division. That seems dangerous. That's why I see this as a correctness issue.
x.to_i / y.to_i # to get truncating division
or
x.to_f / y # to get non-truncating division
If fact, if you can't guarantee the type of x and y, then every time you divide, you must write either [...]
Exactly. And I like the terms truncating and non-truncating division that you use because it shows that adding new operators does not mean that they somehow carry type information, it should be perfectly reasonable to use truncating division with floats.
I think the main question to answer is ``What is the common case?''. If you add a method called quotient, how likely is it that there will be a module to alias / to quotient, which almost all programs will end up requiring? If it is very likely, then the name for quotient should be /, and instead of quotient there should be truncated_quotient and a module that aliases / to that.
That is assuming that breaking existing programs until they add require 'integer'
or something is acceptable.
As long as there is some reasonably fast method that is a guaranteed non-truncating division, I'll be much happier, although all my programs will end up aliasing / to whatever it is.
1. Where will this method be defined?Each numeric class, like other numerical operators.
2. How will it handle new numeric types? (suppose I add a BigFloat type)By coerce system, like other numerical operators.
3. How will you determine what kind of division is required?I'm not sure what you mean. If you want precise division, use the new method, otherwise use '/'.
4. If it is determined by a parameter, then would it be reasonable to divide this one giant method into many smaller methods?We chose coerce system for numeric type mix. It's done before this division discussion.
I think the main question to answer is ``What is the common case?''.It depends person to person, program to program. I myself have almost never used int/int -> float division. I guess this kind of problem should be solved by selector namespace or similar technology.
I'm not sure what you mean. If you want precise division, use the new method, otherwise use '/'.
Your original statement was that you would add "a new method for more accurate division, that returns most accurate division (Float by default, Rational if you require 'rational')." My question is how you would determine what the most accurate division is (particularly for and between user-define numeric types).
BTW (slightly off-topic), is there anything happening in Ruby with regard to ? Would this be useful here?
Your original statement was that you would add "a new method for more accurate division, that returns most accurate division (Float by default, Rational if you require 'rational')." My question is how you would determine what the most accurate division is (particularly for and between user-define numeric types).
7/3
gives the rational number 7/3, while7 .div 3
gives 2 (C-like integer division), and7 .divmod 3
gives [2, 1] (integer division with remainder).Rather than needing an RCR, I think this issue could be addressed by popularizing the mathn standard library (which is not mentioned in the pickaxe book or the bezoar-goat book).
Regards, oinkoink (I haven't yet figured out how to put my name in the header!)2/3 == 0.666..and I don't feel like changing to a different language if I only need to make a couple of quick calculations. Take for example the current implementation of the Matrix#inv method, as implemented in the standard library 'matrix'. Right now, because of this IMHO weird semantics of :/, you get
require 'matrix' p Matrix[[2.0, 3], [3, 4]].inv #=> Matrix[[-4.0, 3.0], [3.0, -2.0]] p Matrix[[2, 3], [3, 4]].inv #=> Matrix[[1, -1], [-1, 1]]Not that is a big issue, but this type of "dynamic behavior" gives probably every mathematician a big grin.
From what I can tell, require 'mathn'
satisfies me.
I'd still be happier if it was the default behavior, but I'll live.
It is definitely the case that mathn needs more publicity.
I see why this would be annoying, but there are also good reasons for keeping both integer and floating point division around. (when working with atomic things like pixels, files, array entries, etc. )
If this is an application specific problem, you can have a require that would redefine division appropriately...
I don't know what :'symbol name' is (Ruby 1.6.5 certainly doesn't like it), but I can create a symbol with spaces using:
'a b c'.intern()
Example: we want to set instance vars from a hash argument and let the user specify either a symbol or a string for the parameter name:
def do_something(hash) @foo = (hash[:foo] or hash['foo'] or default) @bar = (hash[:bar] or hash['bar'] or default) endIf we treat symbols as string literals, we still have to do the above, but with one less
or
case.
I'd rather see changes that improve programming efficiency by a large marrgin rather than satisfy various semantical concerns.
- Leon Torres
When I run into this problem and I meant to have an empty String returned if I'm out of bounds, I just run the result through it's to_s method. That gaurentees that I have a String. I suspect that someone out there relies on the behavior of nil being returned if you are out of bounds, and since the such a simple solution exists I'm not so big on making that change.
However, I'm not against this idea either. I'm torn on the issue of which behavior goes with the principle of least surprise, since either one could be legitimately expected by reasonable people. And given that, I don't think it ought to be changed since there may be code out there that expects the current behavior.
uniq!()
on the result. That is, a difference operator which treats arrays as bags, rather than sets (which we already have) is needed. I wrote a some time ago, but there may be better implementations. Note, this is needed as an addition to existing subtraction methods, not to replace them. I would be happy if it were called bagminus or bag_minus, for brevity.
def initialize(n) @value=n end def coerce (number) [Foo.new(number), self] end def | (n) if n.is_a? Foo @value | n.value else @value | n end end..does not work as intended. It looks to me like this ability could easily be added in numeric.c - how about it?
data = File.open(name) {|f| f.read}and in 1.7, there's
data = File.read(name)
The following is from rubyzip (slightly modified). It is not to be understood as a recommendation, rather something to get the ball rolling, discussion-wise.
Thomas
# relies on: inputFinished?, produceInput and read module ConvenienceInputStream include Enumerable def readlines(aSepString = $/); end def gets(aSepString=$/); end def flush; end def readline(aSepString = $/); end def each_line(aSepString = $/); end alias_method :each, :each_line end #relies on
There are several conceptual layers to the I/O process that are modeled by various abstractions in the OOC
library. Their relationships are shown here:
data locations - where data resides (raw data).
| (e.g., hard disk, memory block, keyboard port, RS232 links)
|
|
channels - connections to data locations in the form of byte streams.
| (e.g., files - on disk and in memory, pipes,
| TCP/IP connections)
|
basic riders - basic operations on bytes.
| (e.g., SetPos, ReadByte, ReadBytes, WriteByte, WriteBytes)
|
|
mappers - translations of high level data to and from a byte stream.
(e.g., binary reader/writer, text reader/writer)
A data location (or simply location) is a source of input data or destination of output data. It it the physical or
logical place where data exists; say a hard disk, or keyboard buffer.
A channel is a connection to a data location. A channel is envisioned as a contiguous sequence, or stream, of
bytes. Channels may be sequential as in the case of terminal I/O, a TCP stream, pipes, and so forth; or positionable
like Files and ProgramArgs.
Riders are associated with a channel and provide read and write access of a location; they operate directly on a
stream of bytes (i.e., a channel). Multiple readers and writers can exist for a single channel.
A mapper is a high-level rider; it operates on a particular format of data, like textual or binary
representation of elementary data types. Mappers rely on the primitive operations of basic riders to build more complex operations.
The benefit of differentiating these layers is allowing a way to distinguish between the simple access layer, that
doesn't know a thing about the byte stream being read or written, and the interpretation layer that transforms bytes into useful data.
I don't like either suggestion, but each for a different reason.
Given how Arrays are implemented, in general (I don't know Ruby's specific implementation but I'm sure it can't be far off), I would expect that this Array#merge would have to traverse the whole Array to figure out if the new element is already present. This is not a task that an Array is designed to do. Also, while it may be a useful method to have for you, I just see it cluttering up the namespace with a method that encourages a poor use of an Array.
When I want to do what you do, I use an Array and a Hash in parallel. Check the Hash for existance, and then push onto the Array if there was no previous existance (as well as update the Hash). The performance difference once there are several thousand elements in the Array should be easily noticable. I haven't abstracted it to a separate class as I should, but I haven't decided the best way to do that, and I'm still relatively new to Ruby.
Also, having Array#merge might even provide a false sense of efficiency to people that don't know how Arrays are implemented.
On to Array#squeeze. I think this is a fine method to have and use in your private library, but I don't think it belongs in the standard Ruby distribution. I think its use is too specialized to allow the intrusion of another name in the Array namespace. I feel the same way about String#squeeze, too, but hoo-hum that's already there.
If you can point out some general uses for squeeze, then I can be turned around on this one. Just because I can't think of one doesn't mean I've closed my mind to the possibility that they exist. But remember, you have to convince me that a fair number of people would want to use this method to turn me around on this.
a = d + b / cTo quickly see what the subexpression (b / c) is producing, make the following simple edit:
a = a + p(b / c)or, to provide a "caption":
a = d + p("***** b / c:", b / c)Note that returning the value will cause it to print the value in an irb session (in addition to its printed output), BUT, p isn't often used at the top level in an irb session since just entering an expression prints its value.
println("a", "b")would be equivalent to
print("a", "b", "n")I favor this additional method because it better expresses the programmer's intent in the method name and, well, it just looks better!
Note that this is different from the existing "puts" method, which prints each of its arguments as separate lines.
I chose the name println because it is similar to names of functions with the same semantics in other languages (e.g. Java, Pascal).
You could, rather than add a whole new method just for a join and a newline, use the String Append operator instead of commas:
puts "a" nil
You could, rather than add a whole new method just for a join and a newline, use the String Append operator () instead of commas:
puts "a" nil
Specification:
class String alias old_count count def count(*args) if args.length == 1 && args.first.kind_of?(Regexp) count = 0 scan(args.first) {count += 1} count else old_count(*args) end end end
Scan works just fine by itself:
"foobarbazbingbong".scan(/[aeiou]/).length ==>6
I suggest the following two new methods in class Dir:
Dir::children(path) produces an array of child entries (similar to Dir::entries but excluding the special entries).
Dir::each_child iterates over child entries (similar to Dir::foreach but excluding the special entries).
I propose that the built-in Mutex be implemented as recursive.
There is no use at all in having a non-recursive mutex. Non-recursive mutexes are sometimes available in thread libraries, but they are only for extremely performance-sensitive applications where saving a machine cycle is paramount. In a high level language such as Ruby, a non-recursive mutex is unnecessary and all-too-likely to cause deadlocks.
There's already a library included with Ruby that does what you want. It's called Sync. It not only allows recursive synchronization, but it supports 2-phase locking as well (shared vs. exclusive locks).
Simple (contrived) example:
use 'sync'; @foo = true; @mutex = Sync.new def falsify_foo # Shared lock -- multiple threads # can access as read-only @mutex.synchronize( Sync::SH ) { if @foo # Exclusive lock -- only one thread # can modify @foo at a time @mutex.synchronize( Sync::EX ) { @foo = false } end } endHope this helps.
class Dir def Dir.mkdirhier(dir) begin Dir.mkdir(dir) rescue Errno::ENOENT Dir.mkdirhier(File.dirname(dir)) Dir.mkdir(dir) end end def Dir.rmdirhier(dir) # # Exit when dir == "." or dir == "/" # return if dir.match(/(?:(^.$|^/$))/) begin Dir.rmdir(dir) rescue SystemCallError return end Dir.rmdirhier(File.dirname(dir)) end end
rescue Errno::EEXIST return
require 'ftools'
File.makedirs( "my/directory/here" )
packed.to_s.reverse!.to_i
Kernel::endian
would return Kernel::BIG_ENDIAN
, on little Kernel::LITTLE_ENDIAN
def someValue return @blah end returnImmutable :someValueRuby wouldn't have to change.
6) What was the original reason for Ruby's returning the last value anyway? Is this an important enough reason to keep this behavior?
alias :foo :bar
I suggest that both the current behaviour and the following should be valid: alias :foo, :bar
alias( :foo, :bar )
This would be more in line with POLS and I doupt it would break any existing code.
Normally arguments are comma separated in ruby, "alias" is an exception to this rule, however:
alias :foo :bar
I suggest that both the current behaviour and the following should be valid:
alias :foo, :bar
alias( :foo, :bar )
alias :foo, :bar alias( :foo, :bar )
line = prefix + number
where prefix
is a string and number
is not. Even Java automatically calls toString on objects that are added to strings, and it doesn't even support overriding operators! (at least the last time I checked :) It's easy to change String#+ yourself to automatically call to_s, but it seems so useful and issue-free to me that it should be default behavior.
An issue with this is that it destroys associativity of addition, i.e.
"ho " + (1 + 2) ==> "ho 3" ("ho " + 1) + 2 ==> "ho 12"
Personally I think it is best to be as explicit as possible with type conversions.
// Niklas
s=""+number;Ruby's string interpolation is imho always better. i.e.:
line="some prefix #{number}" or line=prefix + number.to_sIn the second case it is also more readable since you know that
number
is not string (usually) without searching the previous assignment to that variable.
But everyone can see at first glance that the stuff in parenthesis is evaluated first, then the *
and /
operators from left to right, and then the +
and -
operators from left to right.
We don't need in everyday programming that a+(b+c) == (a+b)+c
After some discussion, we realized what he was asking.
Python allows you to pass a mapping (e.g. Hash) as
values to a format string.
(cf. http://www.python.org/doc/current/lib/typesseq-strings.html)
In Ruby, we have format strings, but they only accept a fixed
number of arguments, and are substituted in the order they are provided.
"This is first: %s, and this is 2nd: %s" % ['one','two']
ftext = "%(name)s is %(gender)s. %(name)s is %(age)2d years old"
hash = {'gender'=>"male", 'name'=>"Fred", 'age'=>23}
ftext % hash # "Fred is male. Fred is 23 years old"
However, it seems this is something that could (should?) be easily added
to Ruby itself. It would help those coming from Python, add a useful
feature, and be totally backwards-compatible.
http://www.ruby-lang.org/en/raa-list.rhtml?name=TextFormatTemplate
Guy N. Hurst
ftext = "%(name)s is %(gender)s. %(name)s is %(age)2d years old"basically the same as:
ftext = "@{"%s" % name} is @{"%s" % gender}. @{"%s" % name} is @{"%2d" % age} years old"
Why don't you just use aRange = eval("1..3")
So new and initialize are actually separate methods in different objects. It is possible to rename the instance method to new, but that might be just as confusing. And initialize is probably a better description of its role in the creation process.
class Class def literal(str) result = eval(str) fail "Improper literal string for #{name}: #{str}" if ! result.kind_of?(self) result end endUsage:
r = Range.literal("1..3") i = Integer.literal("12") n = Numeric.literal("42") n2= Numeric.literal("3.1416") hex = Integer.literal("0xa5") silly = Range.literal("Range.new(1,3,true)") exception = Integer.literal("Hello") danger = Integer.literal('system "rm -r /"')I wouldn't suggest this for general consumption because of the open use of eval, but it would be OK for careful, limited use.
Regarding the speed of eval, if you are doing IO on a file, I doubt the speed of eval is going to effect you significantly.
Cheers.
Why don't you use "ensure" like:returnval = nil 100.times do |i| if(some check) then returnval = something break end end dosomething else return returnval...that looks sort of messy
begin
100.times do | i |
if(some check) then
return something
end
end
ensure
dosomething else
end
Don't want it to execute if exception thrown (sodell, 2002-04-23 03:24:06)
Using ensure forces the call in the event of an exception. We don't want to guarantee the code is called, we just want to guarantee the return value when the function returns non-exceptionally.
C'mon (adde, 2002-05-03 02:16:13)
But w-h-y add it to the language? Just do it yourself!
def do_something
result='some sort of result'
...
...
return result
end
The existing explicit and implicit return methods complement each other.
This would just add complexity.
Reason for rejection
This RCR buys you little, if any.
RCR 88: allow { } (sodell, 2002-04-21 13:39:17)
Status: Rejected
def allow
begin
yield
rescue
end
end
I use the above method a lot to make calls that either I don't care if they work or not or I'm going to ignore/test their success/failure in another way sometime after the call. Here's an example:
allow{File::unlink("file.tar")}
system("tar cxvf file.tar *.files")
I don't really care if file.tar exists when I try to delete it; I just want it gone before I make the system call to invoke tar.
I have only seen this keyword in one other language. I think this would be a good addition to the core distribution.
Why would we need this? Because I think it encourages elegant code. Some things should be added as libraries, some things should be left to the users to write for themselves, but some things should be given to them from the very beginning and I think this is one of those functions that should just be there for programmers from the get-go.
Comments
preview (sodell, 2002-04-21 13:44:35)
So...is there a reason the preview doesn't look anything like the final post?
allow( *exceptions ) (anonymous, 2002-04-21 18:12:10)
Interesting. I would though prefer a slightly more general definition wich by default would work as you wrote, but could optionally be given a list of allowed exceptions:
allow( SystemCallError, ScriptError ) {
...code...
}
-- Nikodemus
allow (dblack, 2002-04-21 20:51:02)
Hi --
The thing is, though, as it becomes more multi-purpose, it starts to look like just a different conception of how to handle exceptions (as opposed to just using rescue clauses in the code).
Bad idea (cout, 2002-04-22 08:01:02)
Catching all (or even a subset of all) exceptions is a bad idea, since you might catch an exception that was caused by being unable to remove the file. If unlink were unable to remove the file, then it may silently fail.
A better solution is to:
Explicitly catch the exception you are expecting,
Check that the file exists and don't try to remove it if it does not, or
Use File::rm_f instead.
Use "rescue" as a modifier (Nikodemus, 2002-04-22 09:37:20)
Silly me. Something like this is already implemented: you can use "rescue" as a statement modifier.
def alert
puts "Alert"
raise
end
alert rescue
puts "ok"
Produces:
Alert!
ok
Not "bad" (sodell, 2002-04-22 12:46:52)
It's only a bad idea if failure would actually cause problems and if the failure were never checked for.
Sometimes I make calls "just to grease the wheels" so to speak, and if the calls fail, it's ok because I'm doing other checks later, or failure doesn't matter.
Here's another example. Let's say I'm doing a little logging routine, and I want the logging routine to start with a fresh log file every time the program starts. It's the program's job to delete the current log file when it exits so the next time it's started, a new one will be created. Well, let's say it failed to do that one time so the log file doesn't go away on exit. At exit, we don't want a lot of errors to pop-up, so if the old log file can't be deleted, no big deal; we can't do much about right then anyway, especially if the whole system is shutting down. However, on start-up, we DO want to check for an existing log file, and that's where the error of "not deleting the log file" will really be handled.
Not "good", either (devEiant, 2002-05-03 16:08:59)
Your scenario sounds suspiciously like programming by coincidence. If it can fail with no repercussions at all, why make the call?
Reason for rejection
If you want to ignore excpetions, use rescue modifier.
RCR 90: "{|x|...}" as a Proc expression. (matz, 2002-04-21 23:55:46)
Status: Rejected
It may be possible to implement "{|x| ...}" as a literal form of Proc object, which exactly work as "lambda{|x| ...}". I didn't implemented it, because I thought "lambda{|x|...}" is enough, and it would cause shift/reduce conflict. But I think mandatory "|" after opening brace can solve conflict. It may make Smalltalk lovers happier, but makes the language syntax complex. How do you think? matz.
Comments
something like: (anonymous, 2002-04-22 01:25:24)
Need some examples...
So it could work something like:
{| puts "Boo!"}.call #-> "Boo!"
or would it be:
{|| puts "Boo!"}.call #-> "Boo!"
Examples (matz, 2002-04-22 02:35:17)
{|| puts "Boo!"}.call #-> Boo!
a = {|x| puts x}
a.call(5) #-> 5
def foo(n)
{|x| x*n}
end
b = foo(6)
p foo.call(4) #->24
p foo.call(8) #->42
matz.
I have two concerns:
As you stated in [], performance is an issue. Creating a proc implicitly might hinder performance;
There is an ambiguity to consider:
def foo(*x, &y) # ... end foo { |z| # ... }
Is this passing a proc in as the argument to foo, or is it passing a block in with no arguments?
Explicitly using Proc.new/proc/lambda is sufficient in most cases, and is not too inconvenient.
Your second concern is a serious one. Probably
foo {|x| ...}will be the block to the method "foo", but it may still confuse programmers.
matz.
proc{}
" vs "{||}
").
I think the additional complexity and potential ambiguity weighs against this idea. Unless I see stronger arguments for this, I think I would pass on this suggestion.
I don't think writing proc { }
is any trouble at all, and it is a lot clearer that there's a proc object being created than simply writing {|| blah}
.
I am also uncertain why the || would be needed. Does a plain { ... } literal have some other meaning?
"&" is already used to convert blocks to procs and back. Why not use it?
&{ ...code...}
Would be rather unsurprising as a proc literal...
Same applies to:
proc |var| ...code... end
and
lambda |var| ..code... end
proc {}
looks visually very like proc ()
-- indeed it looks more like a method call than an constructor of a literal.expr, expr
is a valid statement...def work(x,y) myblock
for example....proc
...end
and lambda
...end
, I could live with those, after all, def
creates a method object.i = 10 i.prev >> 9In tight loops this is faster than writing:
i - 1 Index: numeric.c =================================================================== RCS file: /src/ruby/numeric.c,v retrieving revision 1.42 diff -u -r1.42 numeric.c --- numeric.c 2002/04/10 08:45:22 1.42 +++ numeric.c 2002/04/23 22:02:49 @@ -952,6 +952,17 @@ } static VALUE +int_prev(num) + VALUE num; +{ + if (FIXNUM_P(num)) { + long i = FIX2LONG(num) - 1; + return rb_int2inum(i); + } + return rb_funcall(num, '-', 1, INT2FIX(1)); +} + +static VALUE int_chr(num) VALUE num; { @@ -1656,6 +1667,7 @@ rb_include_module(rb_cInteger, rb_mPrecision); rb_define_method(rb_cInteger, "succ", int_succ, 0); rb_define_method(rb_cInteger, "next", int_succ, 0); + rb_define_method(rb_cInteger, "prev", int_prev, 0); rb_define_method(rb_cInteger, "chr", int_chr, 0); rb_define_method(rb_cInteger, "to_i", int_to_i, 0); rb_define_method(rb_cInteger, "to_int", int_to_i, 0);
In Ruby (as in Java) the ability to declare parameters and returnvalues as const are even more important than in C++ since everything is passed by reference.
Without const correctness, the encapsulation that a class provides can easily be broken by mistake by modifying the wrong reference(s).
I fully aware of the builtin ability to freeze an object, but that's a different thing alltogether. You don't wan't to freeze the object, you wan't to prevent modifications thru a reference to the object. Also, freeze can't be used to declare methods as non-modifying (const).
And no, it wouldn't clutter up the language. If you don't want to use it you wouldn't have to. Allthough i'd recommend you to at least consider it.
def fun1 const param
param.capitalize!
end
var="value"
fun1 var=> Error, const param can't be modified
---
class Foo
def method1 param const
...
end
def method2 param
...
end
const def method3 const
end
end
const bar=Foo.new
bar.method1 => OK!
bar.method2 => Error, non-const method
called for const object
var=bar.method3
var.capitalize! => Error, const object can't be modified
const def get_bar
"hello"
end
b = get_bar
b.capitalize! #=> error
a = b
a.capitalize! #=> error (presumably)
In C++, I might have this:
void foo(const int & x) { x += 1; // error: x is a const reference } void bar() { int x; foo(x); x += 1; // x was const inside foo, but can be modified here, // because it wasn't frozen }
I might also have this:
class Bar { void modify(); // a non-const member function }; class Foo { public: const Bar & bar() const { return x_; } private: Bar x_; }; ... Foo f; f.bar().modify(); // error: f.bar() returns a const reference const Foo f2; const Bar & b(f2.bar()); // okay: Foo::bar() is a const member function
In C++ I have:
class ConstWrapper
def initialize(delegate, *methods_to_skip)
@delegate = delegate
skip_names = methods_to_skip.collect { |symbol| symbol.to_s }
skip_names += self.public_methods
skip_names -= ['to_s', 'to_a', 'inspect', '==', '=~', '===']
for method_name in delegate.public_methods
next if method_name[-1] == ?! or skip_names.include?(method_name)
eval(
const foo=Bar.new
class Foo
const :bar
def bar
end
end
class Foo
def bar
const @foobar
end
end
class NonConstMethodException
Sourcecode (adde, 2002-05-02 07:58:26)
It would be really nice if the preview would cut the comment to make it look like it will when you post it.
I have no place to put the sourcecode, but you can email me (adde@restech.se) if you want it.
owner? what owner?? (patsplat, 2002-05-02 12:25:41)
Who or what is this owner? The programer writing the code? The class?
I think it'd make Ruby better. (anonymous, 2002-05-02 18:55:54)
I voted "good idea". The "opposition" in the long argument earlier didn't seem to understand the concept of a const reference at first, and then got so attached to his opinion that he didn't want to change it ;-)
Ruby is the first language I've found that cleanly and intuitively implements accessor methods (usually achieved with
getFoo()
and setFoo()
) : by making them look like you're accessing the object's attributes directly, but at the same time allowing the class to control the access. But when a getFoo()
method returns a reference to an instance variable (ie. any instance variable that's not an immediate value), the encapsulation is again incomplete: you can modify the object (which is part of another object's internal state), or even change the whole object with replace()
in some cases.
The current way of preventing this is to return a clone of the instance variable. But this isn't a good solution in some cases. If the object is big and heavy, it takes a lot of resources to clone it (especially if it's done thousands or even hundreds of times), and it will have been for nothing if the user of the object doesn't even try to change it.
But instead of adding "const" keywords in illogical places all around method definitions, maybe there could be a lightweight "copy-on-write" cloning mechanism? It would first create just a light proxy that accesses the original object. This proxy would treat the original object as "virtually frozen", and if the caller tries to do something that changes the object, then it would clone the original and forward all subsequent calls to the new one.
But I'm not clear on how the checking for frozenness is implemented in the first place, so I'm not sure if this idea is doable. I'll leave that question to the philosophers (and creators of the language :-)
P.S. patsplat: the owner would be any code that has a "clean" reference to the object, and not a "const" reference.
a = b
a.capitalize!
would capitalize a copy of the attribute, which sometimes isn't what the programmer wants (he might think he is capitalizing the attribute itself)... The compiler should complain about this, and simply NOT allow to modify the value returned by the accesor, nor to copy the reference to it.
If we had static typing, we'd check the constness of the references each time they're assigned from/to (at compile time, of course), but as we don't have it, maybe one solution would be to introduce a special constref dynamic type, which cannot be assigned to anything, period.
It is not like the black-box ideal that some OO proponents evangelize, but it allows me to extend your classes and objects, knowing you can not stop me.
If you need "const" for yourself, consider using some test library for Ruby (RubyUnit, Test::Unit or another of your choice)
PS: If speed is an issue, Ruby is not your language of choice anyway.
Have you considered any other solutions for the problems arising from returning references from inside a class and thereby breaking the encapsulation?Besides .dup, that is.
"freeze"?
matz.
class Customer
attr_reader :name
def initialize name
@name=name
end
end
cust=Customer.new
This would prevent any extensions of the class Customer where you need to modify the ID.
But since the class wasn't designed for that, it's probably a bad idea anyway.
Reason for rejection
This RCR (regardless its static typing or not) will change the language too much.
RCR 94: Optional type checks (chrris, 2002-05-06 13:21:06)
Status: Rejected
Hi all,
Often I find myself writing manual type checks as the first thing in my methods. e.g:
class Foo
def Bar(some, other)
raise SomeException unless some.is_a? Enumerable
# do stuff
end
end
Would it be revolting to allow for optional specification of argument types and let the ruby interpreter to handle these checks and spit out nice error messages (with the calling line) if a mismatch is encountered?
E.g.:
class Foo
def Bar(Enumerable some, other)
# rest assured some is Enumerable and do stuff
end
end
2
Comments
Not convinced (Freaky, 2002-05-06 19:00:32)
I'm typically more worried that an object responds to a particular set of methods than if it's derived from a particular class.
For instance, String
and IO
both respond to each_line
; I typically don't care if it's actually an IO
or a StringIO
or a String
, or a Flurble
object.
Your proposal introduces extra syntax to the language for something I don't think is a particularly good idea in many cases, and for which a shorthand can easily be implimented in the current language, e.g:
def bar(some, other)
some.is_a! Enumerable
end
is_a!
raises TypeError
rather than just returning true/false.
Ruby is not a statically typed language. In Ruby type and class are not related.
The type of an object is defined by, and only by, the way that it responds to messages. Classes and modules define reusable implementations but do not constrain the types of subclasses. It is perfectly reasonable for subclasses to override the implementation of an inherited module or class and to therefore act as a different type. It is also reasonable for a class to implement a type "from scratch" and to therefore be entirely unrelated by inheritance to other implementations of the same type.
For example, if I implemented a class that conformed to the Enumerable type, your code would flag a type error even though the program was type safe.
I think this kind of short cut would be easy to add to the language. It would also sort of answer (some) of the fear of static that people have.
However, as other posters have pointed out, Ruby is completely dynamic. That an object is a kind_of? Enumerable in no way ensures that it will act the way you want to. Even if we put on these extra wheels, those who prefer static typing would discover that they still aren't getting the assurance that they would from Java.
Ruby isn't a staticly (sp) typed language; it shouldn't pretend to be one. Adding this feature would create a misleading appearance of stability, and could be more harm than good. If you want security, Ruby's dynamic typing makes it very easy to write unit tests. This provides much more confidence (in Ruby) than any false static typing constructs.
see aObject.methods, aObject.respond_to?
also,
(aObject.methods & expected_methods) == expected_methods
Would it make sense to introduce the concept of an optional type into a dynamic language?
def method(Type a)
would make the interpreter call the method Type passing a as argument, wich should return an object of class Type.
$:
, do you really think it's sensible to walk them all and possibly hit the wrong file?require 'foobar'
, foobar
isn't there, and end up loading a completely different foobar
. Little children will probably cry as they get frustrating and difficult to trace errors.In the current require semantics, I can hide setup.rb in a "namespace" (a subdir), and I can structure these "namespaces" isomorphically with Ruby namespaces.
In terms of forcing them to use directories for libraries: I'm not sure how the recursive scan would help. That's just a matter of making polite suggestions to the authors.
This sort of is related to a suggestion I made to allow require 'aDir'
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/39025
However, the consensus from the list was that it was not necessary.
I think the point is that if the libraries are disorganized, require will always be difficult. Instead of beefing up require, the libraries should be organized.
~ Patrick
Don't force them, fork them.
Take the project dir, reorganize the source, make sure as much of the build scripts continue to work, etc. Make it clear that the purpose of this fork is to improve some problem with the way the files are organized.
then...
Politely present it to the maintainer:
"Here's a fork. Here's why I did it."
If they disagree with your suggestions, politely announce the fork publicly:
"I love everything about this library except for the way the src is organized. If you feel the same way, you can download the fork from ______."
If other people agree that you have an important point, the fork will be used. Actual use of a fork is a easier way of justifying a code change. Instead of "I think this, but you think that", substitute "This portion of the community at large agrees with these changes."
After announcing the fork, there are several positive outcomes:
Open Source developers do not work for you; they work for themselves. It is your own responsibility to make things work for yourself. Chances are, you will generate code that is worth releasing publicly.
i'm trying to build a class that needs two sets of methods to be passed into it. at frist i put the two sets of methods into seperate classes and passed them into the main class as part of the initialize method. but doing so dosen't allow one set of methods to call the methods in the other set. then it occured to me, a-ha!, what i need to use are mixins. but this didn't work because the include statement requires a CONSTANT, and i don't know the method's name before hand! oh-no! is this a limitation of ruby? can ruby be changed to accomadate this? or is there already a way to work around this? here's example code to help:
class MainClass def initialize(class1, class2) method_set1 = class1.new method_set2 = class2.new end def say_stuff method_set1.say1 method_set2.say2 end end class MethodSet1 def say1 puts "Hello World!" end end class MethodSet2 def say2 puts say1 # won't work end end main = MainClass.new(MethodSet1, MethodSet2) main.say_stuffon the other hand:
class MainClass def initialize(class1, class2) include class1 # not a CONSTANT error :( include class2 # not a CONSTANT error :( end def say_stuff say1 say2 end end module MethodSet1 def say1 puts "Hello World!" end end module MethodSet2 def say2 puts say1 # this would work, if not for the CONSTANT errors end end main = MainClass.new(MethodSet1, MethodSet2) main.say_stuff
Here's one drop-in replacement for your initialize, and there are probably slicker ways to do it:
def initialize(class1, class2) (class
Please don't take offense at this, but it's probably best to bring things like this up on #ruby-talk/comp.lang.ruby, rather than start by suggesting a change to the language. You'll find lots of help, and often lots of different idioms for doing what you want to do.
class MainClass def initialize(class1, class2) extend class1 extend class2 end def say_stuff say1 say2 end end module MethodSet1 def say1 puts "Hello World!" end end module MethodSet2 def say2 puts say1 # this would work, if not for the CONSTANT errors end end main = MainClass.new(MethodSet1, MethodSet2) main.say_stuff $ ruby 1.rb Hello World! Hello World! nil
days = Hash.new days[Apr] = 30 # identical to... days['Apr'] = 30Coming from Perl, you don't realize how much you miss this until it's not available.
This isn't a big issue, I just thought I'd see what people thought.
h = {}
h["the answer"] = 42
h[42] = "the answer"
h[[1,5,10]] = "My key is an array"
infile = File.new("mystuff")
h[file] = "my stuff. keep out!"
Obviously, having the hash index operator automaticly quote it's contents would completely defeat this capability.
BTW, to save a keystroke in hash indexes, use symbols (:key) instead of strings ('key').
Array.rassoc
and Array.assoc
are a great way to use an Array of Arrays as an ordered Hash. However, if you want to update the data in this structure, assoc
and rassoc
won't tell you where it is, just what it is. You can use find
(etc) to locate it, but this means that you don't make use of [or "leverage" if you prefer :-)] the fact that (r)assoc "knew" where the data was when it found it.
Since (r)assoc just returns the whole subarray, what about rassoc_index()
which would behave exactly like (r)assoc, but return the index, so you can pass that into Array.[]
to read and/or change the data there?
I think it would ease the creation of these nested structures, which would make assoc
and rassoc
more useful.
irb(main):001:0> x = [ [0, 1], [5, 6] ]
[[0, 1], [5, 6]]
irb(main):002:0> y = Hash[*x]
{[0, 1]=>[5, 6]}
In any case, a couple of things to note:
irb(main):031:0> h={1,2,3,4} {1=>2, 3=>4} irb(main):032:0> h.collect do |k,v| 10 * k end [10, 30]
the best posted answer to a password generation query, were something in the line of:
def generate_password(minlength=5, maxlength=10) chars = ("a".."z").to_a + ("A".."Z").to_a + (0..9).to_a wordlength = rand(maxlength - minlength + 1) + minlength (1..wordlength).collect { chars[rand(chars.length)] }.to_s end
to me, the following is more elegant, and it illustrates the modification that i request at two places:
def generate_password(minlength=5, maxlength=10) chars = ("a".."z").to_a + ("A".."Z").to_a + (0..9).to_a #usage 1: wordlength equals a random value in the range wordlength = (minlength..maxlength).rand #usage 2: a random character is retrieved from chars array (1..wordlength).collect { chars.rand }.to_s end
i therefore request that a rand method is added to Enumerable. the retrieval of a random element from an enumerable construct is a very common practise, and therefore i believe that it is worthy of presence as part of the Enumerable mixin. seeing arr[rand(arr.length)] is a burden to behold
an alternative is to overload the rand kernel function so one can say: rand((10..20)) in addition to rand(int). this would seem more consistent, but less beautiful
in fact the only use they seem to have is for code organization
this is not trivial
for they would be of great use if they were tied to their "nest-parent"
This would tie namespace organization with the implementation. Currently, User could be a data object, and User::Login could be a statement object which logs in the user. Currently, these two classes can have totally different interfaces appropriate to their different purposes. Binding them together would break this.
i do not know how hard this would be to implement
This behavior sounds like a form of inheritance to me. implementing it might be easier than you think :-)
later,
~Patrick
The reason inner classes are so useful in Java is that Java doesn't have closures. Ruby's closures have all the power of inner classes, with considerably more flexibility.
If you're trying to emulate Java's anonymous inner classes (nameless inner classes defined within a method), you can do something very similar with singleton classes defined within methods.
class Class INEW_MISSING = %q{ def method_missing(m, *a) if a.empty? eval("#{m}", INEW_BINDING) else eval("#{m} *ObjectSpace._id2ref(#{a.id})", INEW_BINDING) end end } def inew(b, *args) const_set("INEW_BINDING", b) module_eval(INEW_MISSING) alias_method :initialize, :instance_initialize obj = self.new(*args) end end class P attr_reader :x, :c def initialize @x = 10 end def y puts "self.name" end def z(n) puts "self.name #{n}" end def make_c @c = C.inew(binding) end class C def instance_initialize puts "Instance initialize with whomever's binding." end def all puts "#{x}" y z 20 end end end p = P.new p.make_c puts p.c.x p.c.y p.c.z 20 p.c.allnotice the lack of @ on the x in class C! spooky. only downside is having to pass the binding with Class#inew. also notice that C dosen't have to be defined in P for this to work. if Class#inew were to be implemented as a standard part of ruby these short-comings could be remedied. okay, someone prove to me why this is a bad idea. ;-)
require 'delegate' class P # ... # Most of P stays the same ... see the original example # ... def make_c @c = C.new(self) end class C What is missing from this technique that is included in the RCR? I see two things ...
new
. Annoying, but not a show stopper.I haven't seen a big need for this idiom in my own code. Would you mind posting some examples where this would be a big win?
What you are asking for sounds a lot like delegation. Have you checked out the delegate.rb file that comes with Ruby? Your example could be rewritten as this ...
require 'delegate' class P # ... # Most of P stays the same ... see the original example # ... def make_c @c = C.new(self) end class C < DelegateClass(P) def all puts "#{x}" y z 20 end end end p = P.new p.make_c puts p.c.x p.c.y p.c.z 20 p.c.allWhat is missing from this technique that is included in the RCR? I see two things ...
new
. Annoying, but not a show stopper.class Parent ...(parent_stuff)... private instance_class Child def instance_initialize ... end end endor the instance_class line could read, "class Child
class Nested The example in my original post didn't have an initialize method, so the default one was inherited from DelegateClass(Parent).
Sounds like a problem with initialize in your delegating class. Did your delegating class have an initialize method? Did the initialize method explicitly pass the "delegatee" object to super? It should probably look like this (warning ... untested code):
class Nested < DelegateClass(Parent) def initialize(delegatee, other_args) super(delegatee) # more code end endThe example in my original post didn't have an initialize method, so the default one was inherited from DelegateClass(Parent).
class P attr_reader :x def initialize @x = 10 c = C.new(self) end class C def initialize(p) puts p.x end end endmy original thought on all this was that passing the parent's self should be implicit since it is a NESTED class. seemed to me they should do more than just organize code, but i digress.
If you want a class that only the "parent" can see that inherits from itself, try this:
class Parent @@innerClass = Class::new( Parent ) { self.class_eval %{ def initialize puts "I'm a child" end } } def initialize @myChild = @@innerClass.new puts "Created inner child #{@myChild.inspect}" end end p = Parent::new p2 = Parent::new
Array#rotate!(index)
rotates self and places the element was at index
at first position.Array#rotate(index)
returns rotated new array.
[1,2,3].rotate(1) #=> [2,3,1] [1,2,3].rotate(-1) #=> [3,1,2] [1,2,3].rotate(3) #=> IndexError
rotate(n)
, I would interpret it a rotate this n times:[1,2,3].rotate(3) #=> [1,2,3]
rotate(i)
to relatively rotate the elements n.abs
times right/left (depending on the sign of n).
rotate_to(i)
sounds good.
arr.rotate_to(i) = arr.rotate(arr.length - i)is that the right calculation?
arr.rotate_to(i) == arr.rotate(i)
Ruby already allows you to shortcut the begin...rescue...end syntax in method definitions with:
def method #... rescue Exception #... end
I suggest extending this syntax to do...end, so that do...rescue...end becomes legal.
The motivation for this pertains to threads. Right now, exceptions occurring in threads are silently swallowed by Ruby, so exception handling in threads becomes:
my_thread = Thread.new do begin #... rescue Exception #... end end
With the new block syntax, this would become:
my_thread = Thread.new do #... rescue Exception #... end
This syntax of course would be usable anywhere blocks occur, and I believe it would make the overall syntax cleaner and encourage responsible exception handling.2
For example ...
my_thread = Thread.new { #... rescue Exception #... }
do
...end
syntax only, by changing just 2 lines in parse.y
.
making code readable is as important as backwards compatiblity (if not more...).
:initialize is a bear to type. I don't think the idea of an alias is bad, but :init isn't a good one.
:setup reads better than :initialize, but it's too entrenched in the ____Unit frameworks.
Any good synonyms?
~ Patrick
def []
nil
end
undefined method '[]' for nil (NameError)
The four functional style Kernel conversion methods (Float, Integer, String, Array) are ideologically stricter than to_f, to_i, to_s, to_a, but there is no way to capture this difference in user-defined classes.
If functional style methods would use to_flt, to_int, to_str, and to_ary methods to convert their arguments users could utilize this distinction in their own classes.
See for example:
If they were removed, the "new" shortcut could be implemented: "SomeObject.new(1,2)" would be "SomeObject(1,2)" instead.
Hmmm, I just noticed that the shortcut might eventually lead to C++ madness. Never mind :)
a = IOString::new a.puts "Hello, world!" str = a.string # maybe a.to_s ? puts str b = IOString::open(str) str = b.gets puts str
I use this kind of structure to store parts of files in place, for parsing later... I created my own class to do this (which was easy, since I knew exactly which methods of IO I'd be talking to), but it seems like something that belongs in the standard library.
# Desired behavior template = 'A8 A8 A16 l' [].pack(template) -> 40 # or perhaps just allow [].pack(template).length # ...and later f = File.new('/var/adm/wtmp') while f.read(len) ...Hardcoding the length in a read operation would be a bad idea since different platforms will return different values. Using my example above, Solaris returns 40 while BeOS returns 36.
See "Perl for System Administration, p.296" for an example of why this would be useful.
*It has been pointed out that Array.new(4).pack(template).length works, but that still requires that I know the record count in advance, which may not always be the case.
t = PackTemplate.new('A8 A8 A16 l') t.length -> 40 (or whatever)Thus, if you just send a string to 'pack()' it would automatically be understood as a PackTemplate object.
However, I can't think of any methods except for 'length' at the moment, so perhaps that's overkill. Feedback/ideas welcome.
p = Pack.new('llll') s = p.pack([42,42,42,42]) p s #=> "*
p = Pack.new('llll') s = p.pack([[0x42424242,0x42424242,0x42424242,0x42424242]) p s #=> "BBBBBBBBBBBBBBBB" a = p.unpack(s) p a #=> [1111638594, 1111638594, 1111638594, 1111638594] p p.length #=> 16This would probably work well as an extension.
Yes, probably. Get started. :)
Seriously, this should probably be submitted as a separate RCR. I don't want to submit it because I don't think I'm qualified to write it.
Any takers?
require 'dl' p DL.sizeof('C8C8C16l') #=> 36The spaces are not allowed, and I used 'C' instead of 'A', because 'A' can vary based on input.
Would it cause any problems if the methods in FileTest
were modified to return a File::Stat object instead of 'true'?
E.g., when doing a recursive comparison of two directory trees,
it's nice not to essentially call stat(2) twice:
Find.find(".") { |afile| st = File::stat(afile) newfile = "../othetree/" + afile if (nst = File.exists?(newfile)) if (st.ino != nst.ino) # do stuff end end }
Same goes for directory?, etc...
Find.find(".") do |afile| begin st = File::stat(afile) nst = File::stat("/somewhere/#{afile}") rescue Errno::ENOENT next end if (st.ino != nst.ino) # do stuff end end
Basically, they return false if the substitution doesn't happen:
class String def subs(pat, sub) tmp = self.sub(pat, sub) if tmp == self return false else return tmp end end end foo = "foo" foo.subs("foo", "bar") # -> bar foo.subs("moo", "bar") # -> falseThe above ruby code would probably best be replaced with smarter C code in string.c .
sub! and gsub! already return nil when the substitution does not occur:
[cout@localhost cout]$ ruby -v ruby 1.6.7 (2002-03-01) [i686-linux] [cout@localhost cout]$ irb irb(main):001:0> s = 'foo' "foo" irb(main):002:0> s.sub!('foo', 'bar') "bar" irb(main):003:0> s.sub!('moo', 'bar') nilInstead of using str.subs, you can instead use str.dup.sub!.
Should Ruby have static typing?
Note: please refer all future ruby-talk threads on this subject to the results of this RCR.
It currently looks like a 'fatal' (i.e. uncatchable) exception is raised when a thread deadlock condition occurs... Of course, this makes debugging these problems a real chore. Would it be possible to change the behavior to raise a Deadlock exception in every locked Thread around these conditions? It'd make it a lot easier to diagnose what's gone wrong.
Here's some example code:
#!/usr/local/bin/ruby require 'Thread' m = Mutex::new m.lock Thread::new(0) { |i| puts 'before' sleep(2) puts 'after' this_will_raise_an_uncatchable_exception m.unlock } begin m.lock rescue puts "Hey!" end
This is USEFULL! I would like to create a mock object, which simply notifies me when a method is called and then hands this call over to the real object the programm was expecting. I can do this with a hack similar to delegates.rb. But it would be much easier and elegant if I could just inherit from, say, Entity and override a private method method_call(:method_name,*args) and state there what to do.
Check out the KernellessObject hack from the excellent RubyTreasures collection:
This may do more than what you want (ie., not only does it not inherit from Object, but it doesn't include the functions from Kernel, either), but it may give you a point from which to start.
I'd like to see an instance method in Array called =~ (just like String) that returns the array index that the string/regex is found in.
That way I can keey the file in an array of strings form from beginning to end instead of flattenning and splitting.
eg (ommitting error-handling). Old style:
data = IO.readlines(filename) data.flatten! startindex = (data =~ BEGIN_BLOCK) + BEGIN_BLOCK.length endindex = (data =~ END_BLOCK) - 1 data = data[startindex..endindex].split("n") yadda...yadda...yaddaNew style:
data = IO.readlines(filename) startindex = (data =~ BEGIN_BLOCK) + 1 endindex = (data =~ END_BLOCK) - 1 data = data[startindex...endindex]This isn't anything major, it would just make stuff slightly cleaner. Additionally, you could do something wacky like this...
lineIndexArray = (data =~ search)Where lineIndexArray[0] is the index into the parent array, lineIndexArray[1] is the index into the subArray, etc. And if the the Array is a single dimension, it would simply return an integer instead of an array...
I'm not sure what you mean about flattening and splitting and all that. If you read a file in with readlines, flattening it won't do anything; that is, you've got a strictly one-dimensional array of strings, so you can't flatten it.
If you're looking to get part of an array based on regex matches, you could use the "flip-flop" operator:
a = %w{one two three four five} a.select {|e| e if /two/.match(e) .. /four/.match(e)} # => ["two", "three", "four"]
class Array def =~( re ) detect { |x| x =~ re } end endIf I were doing a BEGIN_BLOCK and END_BLOCK sort of matching, though, I can think of a lot of other Ruby methods that could work out nicely. The flip-flop in David's example seems exactly what you're looking for. Use with each_line:
buf = "" File.open( filename ) { |in| in.each_line { |l| buf You also don't need to flatten. It's alot more efficient for you to use IO#read directly (depending on your file sizes you may want to read in blocks).
class Array def =~( re ) detect { |x| x =~ re } end endIf I were doing a BEGIN_BLOCK and END_BLOCK sort of matching, though, I can think of a lot of other Ruby methods that could work out nicely. The flip-flop in David's example seems exactly what you're looking for. Use with each_line:
buf = "" File.open( filename ) { |in| in.each_line { |l| buf << l if BEGIN_BLOCK.match(l) .. END_BLOCK.match(l) } }You also don't need to flatten. It's alot more efficient for you to use IO#read directly (depending on your file sizes you may want to read in blocks).
mylibrary/ mytool1/ mytool1.rb index.rb --> mytool1.rbrather than having to do this:
require 'mylibrary/mytool1/mytool1'one could simply do:
require 'mylibrary/mytool1'
mylibrary/ mytool1.rb mytool1/ mytool1.rbNo extension, no new feature, rather simpler.
alias :require_copy :require
def require(file_or_directory)
if File.stat(file_or_directory).directory? then
require_copy "#{file_or_directory}/index.rb"
else
require_copy file_or_directory
end
end
I've tried to debug the BEGIN{} and END{} sections of source file. I can step into the BEGIN one but never the END one. I think it could be interesting to allow to step into or put valid breakpoint in the END{} section. For example I've tried to debug the rubyunit.rb by two way : putting a breakpoint in the END{}section or trying to step into it, but none of the solutions run. it's a pity because it's an entry point and I've lost a lot of time to understand that it was there.
foo/foo1.rb foo/foo2.rb bar/bar.rbNow, if i wan't to require foo1.rb from bar.rb i can just write:
reqire '../foo/foo1.rb'The problem is that if foo1.rb requires foo2.rb like this:
require 'foo2.rb'(Which it should be allowed to do since that's how you normally require files that resides in the same dir as the current file.) Ruby tries to search for the file foo2.rb in the directory where bar.rb is located. Ofcourse, i could just add everything i $LOAD_PATH or whatever, but then how can i descide which file to require when i have two files with the same name in different dirs? I can use module to create namespaces on a class-level, but i can't use dirs to create namespaces on a file-level. I've seen some discussions on this in the mailinglists, but no conclusions.
alias :require_basic :require
def require(file_or_directory)
fp = File.dirname(File.expand_path(file_or_directory))
$:
alias :require_basic :require
def require(file_or_directory)
fp = File.dirname(File.expand_path(file_or_directory))
$:
alias :require_basic :require
def require(file_or_directory)
fp = File.dirname(File.expand_path(file_or_directory))
$: << fp
r = require_basic file_or_directory
i = $LOAD_PATH.index(fp)
$LOAD_PATH.delete_at(i) if i
return r
end
$:
). The current directory ('.'
) is in the load path, so that's one of the places it looks.require 'foo2.rb'
to get foo2.rb
. It would be too easy for someone to place a rogue socket.so
in the same directory as foo1.rb
; then when foo1.rb
goes to require 'socket'
, it would get the rogue socket.so
instead of the real one. That is why '.'
is at the end of the load path; it's a security measure.require
. In RubyTreasures, I used requirelocal
:requirelocal
does a few things:loaders.rb
, all files get required with their full path. Thus, if you requirelocal
a file, then require
the same file, the require
will be a no-op.
alias :require_basic :require
def require(file_or_directory)
begin
fp = File.expand_path(File.dirname(caller[0]))
$: << fp
r = require_basic file_or_directory
i = $:.index(fp)
$:.delete_at(i) if i
return r
rescue
if FileTest.directory?(file_or_directory)
require "#{file_or_directory}/#{file_or_directory}"
else
raise
end
end
end
def import(file_name)
require File.join(File.dirname(caller[0]), file_name)
end
alias :require_basic :require
def require(file_or_directory)
begin
require_basic file_or_directory
rescue
if FileTest.directory?(file_or_directory)
require "#{file_or_directory}/#{file_or_directory}"
else
raise
end
end
end
Really, when you write a == b ==c, what you mean is probably a == b and b == c, which is much more explicit to someone reading your code, and doesn't force weird parsing magic to turn a simple binary operator like '==' into a "magic" operator that chains any number of operands when repeated.
all(a, b, c) == d.
Is there anything like this in Ruby? (If not, it might be easy to add to Object.)
Portage's versioning mechanism is an excellent model:
# In all examples, the require mechanism attempts to use # the most recent (latest) version installed that satisfies # the requirements. # Require exactly version 1.0.1 of package1 require 'package1', "=1.0.1" # Require a version of package2 that is greater than 1.0, but # less than or equal to 2.1.1 require 'package2', '>1.0, <=2.1.1' # Require a version of package3 less than version 2.0 require 'package3', '<2.0' # Use the latest version of package4 installed require 'package4'
This syntax is basically a simplified version of:
require 'package2', Version::range(">1.0, <=2.2.2")
or
require 'package2', ( Version.new("1.0") .. Version.new( "2.1.1") )
This should be part of the standard Ruby installation, rather than an add-on, since it affects core Ruby functions (locating and loading resources), and is of most use to third-party applications (as opposed to local scripts).
#####################################################33 # Version - takes a string in the form: 'X1.X2.X3...Xn' # (where 'Xn' is a number) # ##################################################### class Version include Comparable def initialize(str) @vs = str.split('.').map!{|i| i.to_i} end def [](i) @vs[i] end def to_s @vs.join(',') end def (other) if other.class == String other = Version.new(other) end @vs.each_with_index { |v,i| unless v == other[i] return v other[i] end } return 0 end end module Kernel def require_with_ver(file,&b) if b dir = "" files = [] $:.each {|dir| files = Dir[file+"*"] if files.length> 0 break end } p files files.each { |f| if b.call(Version.new(f.split('-')[1].split(/.rb/)[0])) puts "require '#{f}'" require f return end } else require file end end end if $0 == __FILE__ $: '0.1.1' } end
#####################################################33
# Version - takes a string in the form: 'X1.X2.X3...Xn'
# (where 'Xn' is a number)
# #####################################################
class Version
include Comparable
def initialize(str)
@vs = str.split('.').map!{|i| i.to_i}
end
def [](i)
@vs[i]
end
def to_s
@vs.join(',')
end
def (other)
if other.class == String
other = Version.new(other)
end
@vs.each_with_index { |v,i|
unless v == other[i]
return v other[i]
end
}
return 0
end
end
module Kernel
def require_with_ver(file,&b)
if b #block_given?
puts "block given"
dir = ""
files = []
$:.each {|dir|
files = Dir[file+"*"]
if files.length> 0
break
end
}
p files
files.each { |f|
if b.call(Version.new(f.split('-')[1].split(/.rb/)[0]))
puts "require '#{f}'"
require f
return
end
}
else
require file
end
end
end
if $0 == __FILE__
$: '0.1.1' }
end
In the meantime, why not distribute your versioning code?
There are numerous third-party solutions to this problem. I could have simplified the RCR by simply requesting "Native support for 'require' versioning in Ruby", but I thought I'd mention how I'd like it to look :-).
The problem with third party add-ons is that this really is something that should be native to Ruby, since the final solution will probably affect how packages are installed. Any short-term solution (that I can think of) would break existing Ruby apps. Consider your proposed solution (or mine, for that matter): how would an older app that simply called:
require "package"work? Wouldn't installing this system require that all libraries be re-installed with a special directory structure?
while (true) { do something lines.each do |x| break if isA break 2 if isB end end"break" or "break 1" will exit from the innermost loop, and "break 2" will jump out two loops.
This should also apply to "continue". "continue" or "continue 1" will re-enter the innermost loop, and "continue 2" will re-enter the second-innermost loop.
Exceptions should be thrown when the number is invalid. This might be dangerous in some cases. However it also buys us some flexibility.
loop1: for(...) {
loop2: for(...) {
beak 2
}
}
loop1: for(...) {
newLoop: for(...) {
loop2: for(...) {
beak 3
}
}
}
def isSomethingAvailable something = a_long_call produce("something", something) return !something.nil? end def caller if (isSomethingAvailable) # not necessary to call a_long_call to get it. something = consume("something") end end
In the general case, methods can already return multiple values: they come back as an array:
return 1,2
if block_given?
blockresult = yield more information
end
return result
I'm confused about why you wouldn't want to just use instance variables for this -- the kinds of information you're talking about storing is exactly what instance members and accessors encapsulate very well.
Perhaps a better way to factor the above code, or anything following a similar pattern, is like this:
class MyClass attr_reader :something def isSomethingAvailable @something ||= a_long_call return !something.nil? end # isSomethingAvailable end # class MyClass
That way, you get the benefit of seperately accessing the truth value of isSomethingAvailable, and don't require any funky changes to the language semantics.
Or, just implement produce and consume as module-level methods which use a singleton dictionary/queue/other collection of your choice, and allow arbitrary values to be "tagged" and passed from call to call, object to object, or module to module.
I could definitely see applications where that sort of top-level messaging system could be useful, but I don't think it requires language extensions. You could look at the global DataBus in FreeRIDE for one example of how to implement such a system on top of "vanilla" Ruby.
if val.kind_of?(TrueClass) || val.kind_of?(FalseClass) # or if val == true || val == falseI would like to request a "Boolean" superclass, of which TrueClass and FalseClass would be a subclass. Then, I could simply do:
if val.kind_of?(Boolean)This would both look better and ease my carpal tunnel. I could also then do silly stuff, like create a subclass called "MaybeClass". :)
[1, 2, 3].join(", ") { |v| "(#{v})" } # "(1), (2), (3)"
See the discussion of it, here:
Yes it can be solved by using collect+join.. please read the discussion.
One problem is when #collect and #join is located far from eachother (several lines), then its difficult figuring out what is going on. Array#join which takes a block, can rule out such confusion.
Another problem is that I am lazy and guess others is lazy as well. When im in a hurry, I do like this:
"XXX "+data.join(" XXX ")Which is short, but repeating yourself is bad. I could use collect... but I don't.
Isn't Ruby about making programming easy?
collect-join behavier could be very useful, therefore my RCR proposal. In the discussion I show several example of how it can be used.
pair-join behavier is only little useful.
"I (Jason Creighton) said almost the exact same thing in that thread."
Yes I ripped it from you.. :-)
true... But in Ruby there is already (al least one) example of methods, which behaves radical different if they are supplyed with a block. If given a block to File#open then it closes the file afterwards.
IANYM == I am not Yukihiro Matsumoto
Its this enhancement which can make many things simpler (avoiding typing collect all the time). I think a block supplied to #join is only a minor change.
Im terrible at defending myself in a language which is not my native language. Every time I bring up ideas then everyone is against me.. It would be nice if people would take my side and help me :-)
"To me that is a different operation. It's not just a join!"
Yes.. its an enhanced join which is highly useful :-)
I'd like some way to automate dynamic type checking for method calls. Instead of having to do something like:
def foo(a, b, c) if !a.kind_of?(Numeric) raise ArgumentError.new ("Expected argument a to be of type Numeric") elsif !b.kind_of?(Numeric) raise ArgumentError.new ("Expected argument b to be of type Numeric") end # etc... end
if we had a built-in mechanism to throw these exceptions, it would be great. For example:
def foo(Numeric a, Numeric b, c) # etc... end
could throw an ArgumentError exception if a or b did not return true for kind_of(Numeric).
The problem with this way of handling things is that the exception cannot be caught within this method itself. I was thinking that maybe to allow more flexibility, we could have a keyword called 'type_check' that would check the arguments when invoked. This would allow the exception to be caught within the method itself if desired and also allow some pre-processing code to be added before the type-checking. For example:
def foo(Numeric a, Numeric b, c) a = a.to_f if a.kind_of(String) # If strings were just as good for a begin # Now do type-checking type_check raise ArgumentError => e p e return end # etc... end
So what do you think?
This can be done entirely in Ruby. I implemented multi method dispatching in Ruby which allows you to do this and some other nice things like dispatching based on whether an argument responds to given methods or the like. (There might be a better (faster) implementation for class-only dispatching however.)
My implementation isn't entirely done yet (there's still some documentation missing), but I think that it can serve as an example of the power Ruby gives you nevertheless. See .
Of course there are also benefits of having this build into the language like nicer syntax.
def foo(n:Numeric, s:String)
end
def foo(s:String, n:Numeric)
end
I might want to turn the verbosity level up for all programs so I don't have to add $VERBOSE=true
to the top of every script.
There might be other variables someone would also want to change such as $/
or $
or $-K
.
x=[["name", "john"], ["age", 20]] p x.inject({}){|h,k,v|h[k]=v;h} #=> {"name"=>"john", "age"=>20}
An possible implementation could be:
Also #partition cannot deal with arity> 2..
-- Simon Strandgaard
x=[["name", "john"], ["age", 20]] p x.inject({}){|h,(k,v)|h[k]=v;h} #=> {"name"=>"john", "age"=>20}
#each
. What if it's named something else? What if I have multiple iterators in the same class? For example, String
has #each_line
(aliased to #each
) and #each_byte
. Currently, I can not use #sort
and firends on #each_byte
.
I propose to add an optional parameter to most Enumerable methods to specify which iterator to use. Of course, it would default to #each
so as not to break existing code.
Example usage for String
:
"foo bar".sort # => [ "bar", "foo" ] (uses #each) "foo bar".sort(:each_byte) # => " abfoor"
(I also don't think sort uses each, or any other iterator.)
[pbrannan@zaphod tmp]$ cat test.rb class Foo def each yield 5 yield 4 yield 1 end include Enumerable end p Foo.new.sort [pbrannan@zaphod tmp]$ ruby test.rb [1, 4, 5]
class EnumerableProxy include Enumerable def initialize(iterator) @iterator = iterator end def each(&block) @iterator.call(&block) end end s = "foo bar" e = EnumerableProxy.new(s.method(:each_byte)) s.sort # uses #each e.sort # uses #each_byte
> def collect_attributes > attrs = Array.new > self.each_attribute do |attr| > attrs> But don't you think just being able to say
> elt.collect(:each_attribute) {|attr| ... }> is simpler and more expressive ?
Why wouldn't you just do:
elt.attributes.map {|attr|... }since what you want is a mapping across the attributes anyway? Or if you want an #each-style, rather than #map-style, traversal:
etl.attributes.each {|attr| ...}or if you've defined the separate #each_attribute method:
elt.each_attribute {|attr| ... }
BTW, the arr.map(:meth) {...} syntax, used for a slightly different purpose, has been rejected as an RCR. (May or may not be relevant.)
David
def resume_example(x) begin print x x = x + 4 if x < 10 raise end print x rescue x = 10 resume end end resume_example(5) # -> 510This would compliment retry which returns execution at the top of begin clause rather then after raise. It would also allow better seperation of concern, as you could write an interface on top of a library and report warnings and messages without putting interface code in library.
def resume_example(x) print x x = x + 4 begin if x
Comments
Possible reason for the rejection. (HughSasse, 2001-08-02 06:50:45)
Reason for rejection