Attribute query methods and semantics

109 views
Skip to first unread message

Maksym Melnychok

unread,
May 31, 2012, 8:58:08 AM5/31/12
to rubyonra...@googlegroups.com
Does anyone else finds attribute query methods semantically confusing?

Hi,

Consider this code:

post = Post.new(:visible => true, :url => "http://com")

if post.visible?
  puts "ima visible!"
end

if post.url?
  puts "ima url! (wait wat? o_0)"
end

Does this feel right to you? In case with post.url? i read it as "Hey post object, are you an url?" which is apparently not what the code will do.

So it seems like semantically perfect flag checks go together with totally confusing(for a reader) way of checking whether an attribute is present or not.

I would generate attribute query methods only for boolean attributes.

Regards, Max

James B. Byrne

unread,
May 31, 2012, 9:12:21 AM5/31/12
to rubyonra...@googlegroups.com
I am not sure that I understand your point, but in Ruby anything that
is neither nil nor false is true. Thus returning the url string, if
not nil, is the same as saying that it is true but also allows access
to the actual data without having to send another message.

--
*** E-Mail is NOT a SECURE channel ***
James B. Byrne mailto:Byr...@Harte-Lyne.ca
Harte & Lyne Limited http://www.harte-lyne.ca
9 Brockley Drive vox: +1 905 561 1241
Hamilton, Ontario fax: +1 905 561 0757
Canada L8E 3C3

Maksym Melnychok

unread,
May 31, 2012, 9:23:06 AM5/31/12
to rubyonra...@googlegroups.com
my point is about semantics, not truthiness/falseness of values

post.visible? - is asking post object if it is visible because it has
a flag(boolean attribute) named 'visible'

post.url? - is checking if attribute named 'url' is present or not, and
that is exactly what i find confusing because even though 
syntactically it is identical to flag check, semantically this line looks
like we're asking post object if it is a url which makes no sense.

Regards, Max

Sam Oliver

unread,
May 31, 2012, 9:23:46 AM5/31/12
to rubyonra...@googlegroups.com
On Thu, May 31, 2012 at 2:12 PM, James B. Byrne <byr...@harte-lyne.ca> wrote:

> I would generate attribute query methods only for boolean attributes.

I am not sure that I understand your point, but in Ruby anything that
is neither nil nor false is true.  Thus returning the url string, if
not nil, is the same as saying that it is true but also allows access
to the actual data without having to send another message.

I think Max's point is that "post.visible?" could be read as "post is visible?" but "post is url?" carries a different meaning.

Sam

Jeremy Walker

unread,
May 31, 2012, 9:28:12 AM5/31/12
to rubyonra...@googlegroups.com
Maybe have query methods for boolean attributes and prefixed query methods for not. e.g.
post.visible?
post.has_url?

Or maybe leave the currently methods as they are, but add new prefixed methods, with different prefixes for boolean methods, e.g.
post.is_visible?
post.has_url?
 

Sam

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-co...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.

Richard Schneeman

unread,
May 31, 2012, 9:45:23 AM5/31/12
to rubyonra...@googlegroups.com
I'm -1 on a has_* method

If we want to kill ? on non boolean attributes we should encourage standard @post.url.blank? and @post.url.present? be used instead. The originally proposed change makes sense to me. The question mark character adds nice semantics to boolean attributes. I agree it's not clear what exactly that would do on non-boolean attributes. Removing the questionable methods would help decrease the method count. 

Does anyone really need to use: @post.id?

-- 
Richard Schneeman

Jarrett Meyer

unread,
May 31, 2012, 9:48:16 AM5/31/12
to rubyonra...@googlegroups.com
+1 to Richard. Keep ? for booleans, get rid of the others and use .blank? and .present? as needed.
--
Jarrett Meyer
Email: jarret...@gmail.com
Web: JarrettMeyer.com
Twitter: @jarrettmeyer

Maksym Melnychok

unread,
May 31, 2012, 9:49:46 AM5/31/12
to rubyonra...@googlegroups.com
absolutely agree with all points. i just didn't know if methods count
argument is relevant at all. imo it's a nice side-effect of proposed
change.

Sam
To post to this group, send email to rubyonrails-core@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To post to this group, send email to rubyonrails-core@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com.

Sam
To post to this group, send email to rubyonrails-core@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To post to this group, send email to rubyonrails-core@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com.

Rodrigo Rosenfeld Rosas

unread,
May 31, 2012, 10:17:19 AM5/31/12
to rubyonra...@googlegroups.com
I'd guess methods count is relevant based on this pull request:

https://github.com/rails/rails/pull/5763

Steve Klabnik

unread,
May 31, 2012, 10:27:48 AM5/31/12
to rubyonra...@googlegroups.com
Not using is_ is idiomatic:
http://devblog.avdi.org/2011/04/07/rspec-is-for-the-literate/ (look
for 'There is a different, but related, effect of using RSpec.')

Every Ruby object is truthy or falsey, and so treating them all as
possibly boolean is 100% okay as far as I'm concerned.

Rafael Mendonça França

unread,
May 31, 2012, 10:30:20 AM5/31/12
to rubyonra...@googlegroups.com
Actually the query attribute method does more than check if the value is present. It is very useful for legacy databases where the user persist boolean values as [0, 1], ["t", "f"], ["true", "false"] and more.

I don't see this being removed from rails or changing your behavior.

Also removing it will not decrease the methods count because we still need to generate it for booleans.
To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-co...@googlegroups.com.

Rodrigo Rosenfeld Rosas

unread,
May 31, 2012, 10:41:04 AM5/31/12
to rubyonra...@googlegroups.com
Em 31-05-2012 11:30, Rafael Mendon�a Fran�a escreveu:
> Actually the query attribute method does more than check if the value
> is present. It is very useful for legacy databases where the user
> persist boolean values as [0, 1], ["t", "f"], ["true", "false"] and more.
>
> I don't see this being removed from rails or changing your behavior.

I agree with you on that

> Also removing it will not decrease the methods count because we still
> need to generate it for booleans.

It would decrease because they would *only* be generated for boolean fields.

Maksym Melnychok

unread,
May 31, 2012, 10:48:16 AM5/31/12
to rubyonra...@googlegroups.com
@ Rafael Mendonça França

legacy databases storage must be concern of corresponding database 
adapter, if a field is of boolean type, whatever that means on storage 
level of particular database, that field must be treated as boolean in rails
on the model level.

i'm not suggesting to drop such functionality for boolean attributes, only
for non-booleans where #{attribute}? literally makes no sense when you
read it.

methods count would be decreased because rails would generate query
method only for boolean attributes.

@ Steve Klabnik

syntactically you are correct

but if we decide that there doesn't have to be semantical contribution to 
your code from using attribute query methods then #{attribute}? is just 
a shortcut for !!#{attribute} - so why do we need it in the first place? 
saving 1 character is weird goal here.

if on the other hand we want query methods to provide semantics then
there is obvious conflict with non-boolean fields as semantics there are
different.

Steve Klabnik

unread,
May 31, 2012, 10:50:05 AM5/31/12
to rubyonra...@googlegroups.com
> but if we decide that there doesn't have to be semantical contribution to
> your code from using attribute query methods then #{attribute}? is just
> a shortcut for !!#{attribute} - so why do we need it in the first place?
> saving 1 character is weird goal here.

It's not saving a character. It's that !! is programmer talk, and ? is
human talk. Ruby prefers human talk.

Rodrigo Rosenfeld Rosas

unread,
May 31, 2012, 10:52:01 AM5/31/12
to rubyonra...@googlegroups.com
Em 31-05-2012 11:48, Maksym Melnychok escreveu:
> @ Rafael Mendon�a Fran�a
>
> legacy databases storage must be concern of corresponding database
> adapter, if a field is of boolean type, whatever that means on storage
> level of particular database, that field must be treated as boolean in
> rails
> on the model level.
>
> i'm not suggesting to drop such functionality for boolean attributes, only
> for non-booleans where #{attribute}? literally makes no sense when you
> read it.
>
> methods count would be decreased because rails would generate query
> method only for boolean attributes.
>

I guess Rafael meant another thing. You have boolean fields in
PostgreSQL but someone might prefer to use some old ANSI types, like
INTEGER for storing such booleans for some reason.

Rodrigo Rosenfeld Rosas

unread,
May 31, 2012, 10:56:37 AM5/31/12
to rubyonra...@googlegroups.com
Em 31-05-2012 11:52, Rodrigo Rosenfeld Rosas escreveu:
Em 31-05-2012 11:48, Maksym Melnychok escreveu:
@ Rafael Mendonça França

Actually PG do support the ANSI boolean type. But some will prefer some other ANSI type because other databases don't support the boolean type:

http://en.wikipedia.org/wiki/SQL:1999#Boolean_data_types

Rafael Mendonça França

unread,
May 31, 2012, 10:56:04 AM5/31/12
to rubyonra...@googlegroups.com
And in these cases you don't know if these fields are boolean or not. If you are choose to store the visible column as string ["yes", "no] so you will not have the query method.

I like this method as it is. For me it is very useful and give me the possibility to not care about what is the datatype of the field.
On Thu, May 31, 2012 at 11:52 AM, Rodrigo Rosenfeld Rosas <rr.r...@gmail.com> wrote:
Em 31-05-2012 11:48, Maksym Melnychok escreveu:

@ Rafael Mendonça França

Rodrigo Rosenfeld Rosas

unread,
May 31, 2012, 10:59:57 AM5/31/12
to rubyonra...@googlegroups.com
Another way would add another annotation method to ActiveRecord::Base, like:

boolean_field :incomplete, :disabled, :deleted

This would further document the model mapping and would also allow better semantics.

Not that I really care about this as I don't even use ActiveRecord ;)

Cheers,
Rodrigo.

Maksym Melnychok

unread,
May 31, 2012, 11:05:16 AM5/31/12
to rubyonra...@googlegroups.com
On Thursday, May 31, 2012 4:50:05 PM UTC+2, Steve Klabnik wrote:
It's not saving a character. It's that !! is programmer talk, and ? is
human talk. Ruby prefers human talk.

well your kung-fu beats my kung-fu here

i just don't think post.url? is talking proper human talk to me, i would 
expect answer to that question to be "no, post is not a url" instead i
will get "yes, url attribute is not empty".

> I guess Rafael meant another thing. You have boolean fields in 
> PostgreSQL but someone might prefer to use some old ANSI types, like 
> INTEGER for storing such booleans for some reason. 

i think that first of all this is rather an edge-case that shouldn't force
us to go against least surprise principle

second - this directly goes against Steve's assumption that 

post = Post.new
assert post.id?

should not fail (it fails because 0 is apparently false.. since when?)

i personally think this smells a lot like PHP and it's non-logical,
generally ugly and wrong truthiness/falseness checks

Allen Madsen

unread,
May 31, 2012, 11:10:50 AM5/31/12
to rubyonra...@googlegroups.com
Maybe it is just me, but I don't use features that I don't like in rails, just like I avoid calling private methods. In that sense, there's nothing that is preventing anyone from using `post.body.present?` instead of `post.body?`. My argument would be to let rational programmers decide what is best for their specific case. If you're on a team, set a style guide that picks a winner.
--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-core/-/KND68A_wF8sJ.

To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-co...@googlegroups.com.

James B. Byrne

unread,
May 31, 2012, 11:44:33 AM5/31/12
to rubyonra...@googlegroups.com
This really comes down to ones own understanding of English. Since
visible is a quality of some object one may reasonably infer that
#visible? is synonymous with #is_visible? This might not actually be
the case of course but the inference is strong.

In the case of #url? an url is not a quality, it is an object in own
right even if its representation is wholly contained within the state
of a container object (i.e. an attribute with a string value). I agree
with the OP that in this case #url? is not good form and that #url is
a superior since it imparts the idea that one should receive a
representation and not simply a boolean.

However, #has_url? or #has_anything? to me would be pointless in Ruby.
If an object has one then just tell it to provide it and if nil is
returned then it does not.

Matt Jones

unread,
Jun 1, 2012, 11:03:38 AM6/1/12
to rubyonra...@googlegroups.com
One use that hasn't been mentioned previously - passing method names to things like :if, :unless etc in validations. With the ? version, this can be pretty short:

validates_presence_of :some_attribute, :unless => :some_other_attribute?

The no-? version doesn't do the right thing in many cases (since empty strings evaluate to true), and using present? instead requires a Proc.

Not certain if this is a sufficient argument for the existence of the ? suffix, but worth thinking about.

--Matt Jones

Reply all
Reply to author
Forward
0 new messages