Defining your own typecaster

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.

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 F.
http://www.vinibaggio.com

On [Sun, 25.04.2010 08:37], Josh C. wrote:

out.
They’re actually just methods with an uppercase name.

class Foo
…
end

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

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

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.

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

joe = BaseballPlayer.new(:hits => ‘24’, :runs => ‘12’, :team => ‘Dragons’)

joe.phone_number => 1234567890

joe.runs
=> 12

joe.rbi
=> 0.5

joe.runs = nil

joe.rbi
=> nil

joe.phone_number
=> “(123) 456-7890”


Johnathon W.
Web Application Consultant

http://blog.mustmodify.com/

On 04/25/2010 02:01 AM, Vinícius Baggio F. wrote:

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
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