Project

General

Profile

Actions

Bug #7782

closed

Struct both has and does not have an allocator

Added by trans (Thomas Sawyer) about 11 years ago. Updated about 11 years ago.

Status:
Closed
Assignee:
-
Target version:
ruby -v:
ruby 1.9.3p327 (2012-11-10 revision 37606) [x86_64-linux]
Backport:
[ruby-core:51846]

Description

=begin
One the one hand:

>> Struct.allocate
TypeError: allocator undefined for Struct
    from (irb):1:in `allocate'
    from (irb):1
    from /opt/Ruby/1.9.3-p327/bin/irb:12:in `<main>'

But on the other:

>> Struct.method(:allocate)
=> #<Method: Class#allocate>

In my current case, I need a reliable way to check if a class can be allocated or not. How can one do this if the method is remains present even when it can not be used?
=end

Updated by matz (Yukihiro Matsumoto) about 11 years ago

  • Status changed from Open to Closed

"allocator" in the error message does not mean #allocate method, but internal C function (thus TypeError not NoMethodError).
We haven't provide the way to check if a class can be allocated, except for actually allocating an object.
I don't think we need to prepare the way to check explicitly.

Matz.

Updated by trans (Thomas Sawyer) about 11 years ago

So you think rescuing the error is good enough. Ok, I'll handle it that way. Would it be prudent to make the error very specific, e.g. UndefinedAllocatorError. So that rescue clauses can be sure to catch that specifically?

Updated by matz (Yukihiro Matsumoto) about 11 years ago

I am not positive about adding exception classes. So far, TypeError only caused by inexistence of allocator.

Matz.

Updated by trans (Thomas Sawyer) about 11 years ago

=begin
But is not so nice to have to write code like this:

success = begin
  object = type.allocate
  true
rescue TypeError
  false
end

if success
  ...
else
  ...
end

Instead of like:

begin
  object = type.allocate
  ...
rescue TypeError
  ...
end

Can't do it b/c what if first ... code causes different TypeError?

Actually the more I think about it the more I am inclined to add a core extension:

def try_allocate
  begin
    allocate
  rescue TypeError
    nil
  end
end

Then we could write:

if object = try_allocate
  ...
else
  ...
end

=end

Updated by drbrain (Eric Hodel) about 11 years ago

Sounds like you are reinventing begin; rescue; else; end: https://github.com/ruby/ruby/blob/trunk/doc/syntax/exceptions.rdoc

Updated by trans (Thomas Sawyer) about 11 years ago

=begin
Ah, else. I've never used that, and forgotten about it.

So I should be able to write instead:

begin
  object = type.allocate
rescue TypeError
  ...
else
  ...
end

Reads kind of funny. But okay. I will try that. Thanks.
=end

Updated by trans (Thomas Sawyer) about 11 years ago

Ok. One last comment on this:

I am not positive about adding exception classes. So far, TypeError only caused by inexistence of allocator.

Assessments like "So far", are what make's a coder worry. In future that could change, then my code suddenly has potential error in it. However, I realize this is very unlikely, so I won't fret over it. But unlikely or no, I'd rather have zero probability of worry!

P.S. @drbrain (Eric Hodel) It worked. Thanks again.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0