Defining your own typecaster

J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

Hi, how do you define your own typecaster?

Builtin examples

Array(1..5) # => [1, 2, 3, 4, 5]
Integer(5.2) # => 5
Float(5) # => 5.0


I would expect it to be something like this

class Foo
def self.()(*objs)
Foo.new
end
end

Foo(1)


But that isn't valid syntax, and I'm not sure what to look up to figure this
out.
 
V

Vinícius Baggio Fuentes

[Note: parts of this message were removed to make it a legal post.]

I've seen the following declaration, which I think it is valid:

module Kernel
def Foo(*objs)
Foo.new(objs)
end
end

I'm not sure if there's another way one could achieve that, but works for
the purpose.

Vinicius Baggio Fuentes
http://www.vinibaggio.com
 
D

Dominik Honnef

Hi, how do you define your own typecaster?

Builtin examples

Array(1..5) # => [1, 2, 3, 4, 5]
Integer(5.2) # => 5
Float(5) # => 5.0


I would expect it to be something like this

class Foo
def self.()(*objs)
Foo.new
end
end

Foo(1)


But that isn't valid syntax, and I'm not sure what to look up to figure this
out.


They're actually just methods with an uppercase name.

class Foo
…
end

def Foo(arg)
Foo.new(…)
end

Foo(…) # => #<Foo:0x8ebc4b4>
 
R

Robert Klemme

[Note: parts of this message were removed to make it a legal post.]

I've seen the following declaration, which I think it is valid:

module Kernel
def Foo(*objs)
Foo.new(objs)
end
end

I'm not sure if there's another way one could achieve that, but works for
the purpose.

That's typically how they are done. And I believe methods are also made
private to disallow calling them with self:

irb(main):001:0> Integer("1")
=> 1
irb(main):002:0> self.Integer("1")
NoMethodError: private method `Integer' called for main:Object
from (irb):2
from /usr/local/bin/irb19:12:in `<main>'
irb(main):003:0>

And you should probably forward the block if given. So the complete
idiom looks like this:

module Kernel
def Foo(*objs, &b)
Foo.new(objs, &b)
end
private :Foo
end

Cheers

robert
 
M

MustModify

module Kernel
  def Foo(*objs)
    Foo.new(objs)
  end
end

This is a valid solution to the problem, but I'm wondering why you
want to do type casting. Typically if you're working in Ruby and
you're looking at that kind of declaration, you've come from C# or
Java or something and you just aren't in the groove yet. If you give
us some context, we might be able to give you a better push.

<plug>
I wrote a gem called Valuable ( http://valuable.mustmodify.com/ ) that
implements very simple type casting for instance attributes. It's
useful in situations where like gets and in Rails where your input
often comes in as a string and you don't want to have to worry with
the logic of casting nil.to_i on accident, etc.

class BaseballPlayer
has_value :hits, :klass => :integer
has_value :runs, :klass => :integer
has_value :team
has_value :phone_number, :klass => PhoneNumber

def rbi
(hits / runs.to_f) if hits && runs
end
end
=> 12
=> 0.5
=> nil
=> "(123) 456-7890"

</plug>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top