Submitted by: Bertram Scharpf
This revision by: Bertram Scharpf
Date: Wed Mar 21 15:08:06 -0500 2007
Add a method String#notempty? analogous to Numeric#nonzero?. The method should return nil when the String is empty.
I encountered need of a method like this several times. The last two were:
- Converting an olde fixed-with data field to SQL where strings are not terminated but filled up with spaces.
sqlvalue = record[ 4, 30].rstrip.notempty?
This will insert SQL-NULL when the field was empty.
- SQL-like coalesce:
defaulted = str.notempty? || "(void)"
Extend `string.c’ by 6 to 8 lines of code. See Implementation below.
This change would be trivial. Backwards compatibility problems are not to be expected.
Implementation by plugin would be more uneffective as the macro RSTRING_LEN will not be available by itself.
Another lookahead implementation I use is:
class String method_defined? :notempty? or def notempty? self unless empty? end end
static VALUE rb_str_notempty(VALUE str) { if (RSTRING_LEN(str) 0) return Qnil; return str; } or even static VALUE rb_str_notempty(VALUE str) { return RSTRING_LEN(str) 0 ? Qnil : str; }
This should be preceded by a comment like
/ call-seq: str.notempty? => nil or self Returns self
if and only if str is not empty, nil
otherwise. “hello”.notempty? #=> “hello” ””.notempty? #=> nil /
And later on:
void Init_String(void) { ... rb_define_method(rb_cString, “notempty?”, rb_str_notempty, 0); ... }
On 3/21/07, zimbatm@oree.ch <zimbatm@oree.ch> wrote: > With the same logic, a negative counterpart to every `?`ending method > should be created ? > ... > > What I would prefer, is the `not` keyword to be accepted in the cases > you cite, like : > > x = not "".empty? > > which is more readable than : > > x = ! "".empty? > > and should make you happy :) Actually, the usage is different than you're expecting. The real key (which isn't mentioned in the RCR) is the return value when the receiver is *not* empty. As opposed to most ? methods, it returns self in the true case rather than "true". I was about to write an email about how this felt "wrong", but then decided to check how nonzero? behaves, and sure enough, it is analogous: >> 5.nonzero? # => 5 >> 1.nonzero? # => 1 >> 0.nonzero? # => nil This behavior surprised me, so I'm still not certain how I feel about copying the behavior for nonempty?, but Bertram does have some basis for it. :) The rationale behind this is then the ability to say: my_variable.nonzero? || default_value my_variable.notempty? || default_value If my variable holds a non-zero/non-empty value, the original value is kept; if it holds a zero or an empty string, the default value is used (by returning nil). I'll admit this usage does seem handy, but the name of the methods don't reveal this "feature", which I think is a flaw. Just like you, I had *thought* that nonzero? and notempty? would be equivalent to !zero? and !empty?, respectively, because of the name. In the end, I'm not opposed to having *a* method with this functionality, and by analogy to nonzero?, the name bears a measure of consistency, but I'd still prefer a more revealing name for the method. Jacob Fugal
Hi -- I don't think everyone got Jonas Pfenniger's comment, so I'm cut-and-pasting it here. Also, I've (hopefully) fixed the thing where the URL has the ID number instead of the RCR number :-) Here's Jonas's comment. See also Jacob's reply, in another subthread. David -------------------------------------------------------------------------------------------------------------------------- > Add a method String#notempty? analogous to Numeric#nonzero?. The method should return nil when the String is empty. With the same logic, a negative counterpart to every `?`ending method should be created ? For the fun, I made a small script to count the number of `?`ending methods: --- mmm = [] ObjectSpace.each_object(Class) do |obj| (obj.private_instance_methods + obj.protected_instance_methods + obj.public_instance_metho if m =~ /\?$/ and m !~ /^(not|non)/ mmm << m end end end require 'pp' pp mmm.uniq.size --- That gives me 67 on ruby 1.8.5 without rubygems. What I would prefer, is the `not` keyword to be accepted in the cases you cite, like : x = not "".empty? which is more readable than : x = ! "".empty? and should make you happy :)
On 3/21/07, lukfugl@gmail.com <lukfugl@gmail.com> wrote: > A comment about: RCR 9: Add String#notempty? method > was sent by Jacob L Fugal. > > To send a comment, reply to this mail. Please trim all unnecessary > lines. > > You can view RCR 9 at: > https://rcrchive.net/rcrs/15 > > On 3/21/07, zimbatm@oree.ch <zimbatm@oree.ch> wrote: > > With the same logic, a negative counterpart to every `?`ending method > > should be created ? > > ... > > > > What I would prefer, is the `not` keyword to be accepted in the cases > > you cite, like : > > > > x = not "".empty? > > > > which is more readable than : > > > > x = ! "".empty? > > > > and should make you happy :) > > Actually, the usage is different than you're expecting. The real key > (which isn't mentioned in the RCR) is the return value when the > receiver is *not* empty. As opposed to most ? methods, it returns self > in the true case rather than "true". I was about to write an email > about how this felt "wrong", but then decided to check how nonzero? > behaves, and sure enough, it is analogous: > > >> 5.nonzero? # => 5 > >> 1.nonzero? # => 1 > >> 0.nonzero? # => nil > > This behavior surprised me, so I'm still not certain how I feel about > copying the behavior for nonempty?, but Bertram does have some basis > for it. :) > > The rationale behind this is then the ability to say: > > my_variable.nonzero? || default_value > my_variable.notempty? || default_value > > If my variable holds a non-zero/non-empty value, the original value is > kept; if it holds a zero or an empty string, the default value is used > (by returning nil). I'll admit this usage does seem handy, but the > name of the methods don't reveal this "feature", which I think is a > flaw. Just like you, I had *thought* that nonzero? and notempty? would > be equivalent to !zero? and !empty?, respectively, because of the > name. > > In the end, I'm not opposed to having *a* method with this > functionality, and by analogy to nonzero?, the name bears a measure of > consistency, but I'd still prefer a more revealing name for the > method. This may be a little off beat, but I wonder if Ruby's use of anything but nil and false as true, might not be taken a step further. And rather any object could have a state of true or false. Then conditions could use this state rather than a type, which seems to me to fit better with duck-typing. In other words x = "" x.empty? #=> "" x.true? #=> true y = "123" y.empty? #=> "123" y.true? #=> false x ? 1 : 0 #=> 1 y ? 1 : 0 #=> 0 I'm not sure the full ramifications of this, but it a least seems quite interesting at first glance. T.
On Wed, Mar 21, 2007 at 08:33:33PM -0500, transfire@gmail.com wrote: > A comment about: RCR 9: Add String#notempty? method > was sent by Trans Onoma. > > To send a comment, reply to this mail. Please trim all unnecessary > lines. > > You can view RCR 9 at: > https://rcrchive.net/rcrs/9 > > This may be a little off beat, but I wonder if Ruby's use of anything > but nil and false as true, might not be taken a step further. And > rather any object could have a state of true or false. Then conditions > could use this state rather than a type, which seems to me to fit > better with duck-typing. In other words > > x = "" > x.empty? #=> "" > x.true? #=> true > > y = "123" > y.empty? #=> "123" > y.true? #=> false > > x ? 1 : 0 #=> 1 > y ? 1 : 0 #=> 0 > > I'm not sure the full ramifications of this, but it a least seems > quite interesting at first glance. At the risk of continuing off the beaten path, I've thought about a similar idea whereby Object would have a to_bool method (returning true) and then NilClass and FalseClass would return false and self (respetively). Then object in conditional contexts would implicitly be coerced by calling to_bool similarly to the way blocks are coerced with to_proc. marcel
On 3/21/07, marcel@vernix.org <marcel@vernix.org> wrote: > At the risk of continuing off the beaten path, I've thought about a similar > idea whereby Object would have a to_bool method (returning true) and then > NilClass and FalseClass would return false and self (respetively). Then > object in conditional contexts would implicitly be coerced by calling to_bool > similarly to the way blocks are coerced with to_proc. Ah, nice! One of the things this opens up is the ability to do full method-probing and dynamic backtracking (halting-problem not withstanding). T.
In message "Re: [RCR] Add String#notempty? method" on Wed, 21 Mar 2007 20:41:35 -0500, marcel@vernix.org writes: |At the risk of continuing off the beaten path, I've thought about a similar |idea whereby Object would have a to_bool method (returning true) and then |NilClass and FalseClass would return false and self (respetively). Then |object in conditional contexts would implicitly be coerced by calling to_bool |similarly to the way blocks are coerced with to_proc. It is too risky to decrease performance of the language. matz.
On Wed, Mar 21, 2007 at 08:33:22PM -0500, transfire@gmail.com wrote: > This may be a little off beat, but I wonder if Ruby's use of anything > but nil and false as true, might not be taken a step further. And > rather any object could have a state of true or false. Then conditions > could use this state rather than a type, which seems to me to fit > better with duck-typing. In other words > > x = "" > x.empty? #=> "" > x.true? #=> true > > y = "123" > y.empty? #=> "123" > y.true? #=> false So calling #empty? would change the boolean state of y? How would this work in a multithreading environment? > > x ? 1 : 0 #=> 1 > y ? 1 : 0 #=> 0 > > I'm not sure the full ramifications of this, but it a least seems > quite interesting at first glance. It sounds confusing to me. Paul
On 3/22/07, pbrannan@atdesk.com <pbrannan@atdesk.com> wrote: > On Wed, Mar 21, 2007 at 08:33:22PM -0500, transfire@gmail.com wrote: > > This may be a little off beat, but I wonder if Ruby's use of anything > > but nil and false as true, might not be taken a step further. And > > rather any object could have a state of true or false. Then conditions > > could use this state rather than a type, which seems to me to fit > > better with duck-typing. In other words > > > > x = "" > > x.empty? #=> "" > > x.true? #=> true > > > > y = "123" > > y.empty? #=> "123" > > y.true? #=> false > > So calling #empty? would change the boolean state of y? How would this > work in a multithreading environment? Hmm.. I guess it would be thread critical. More efficiency issues. > It sounds confusing to me. Maybe so. Interesting doesn't necessarily preclude confusing. :-) T.
Copyright © 2006, Ruby Power and Light, LLC
Comments
from Jonas Pfenniger, Wed Mar 21 15:37:11 -0500 2007