Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Safe previous_def #6696

Closed
vladfaust opened this issue Sep 11, 2018 · 3 comments
Closed

Safe previous_def #6696

vladfaust opened this issue Sep 11, 2018 · 3 comments

Comments

@vladfaust
Copy link
Contributor

class Array(T)
  def self.parse(string) : self | Nil forall T
    previous_def

    {% if T == Int32 %}
      return string.split(", ").map{ |s| s.to_i }
    {% end %}
  end
end

class Array(T)
  def self.parse(string) : self | Nil forall T
    previous_def

    {% if T == Float32 %}
      return string.split(", ").map{ |s| s.to_f32 }
    {% end %}
  end
end

class Array(T)
  def self.parse(string) : self | Nil forall T
    previous_def

    {% if T == URI %}
      return string.split(", ").map{ |s| URI.parse(s) }
    {% end %}
  end
end

pp! Array(Int32).parse("1, 2")
pp! Array(Float32).parse("0.5, 42")
pp! Array(URI).parse("foo, bar")
there is no previous definition of 'parse'

I'm trying to achieve an extensible Array parsing, when users of my shard could define their own .parse methods for their needs. So writing every possible type in one file is not an option.

It would be awesome if we could safely call previous_def? or at least rescue it.

I've tried {% if @type.has_method?("parse") %} and if reponds_to?(:parse) - they both return true, but the error is still raised - I guess it's because at the moment when previous_def is looked up in the first method, the second and the third are already defined? IDK.

@vladfaust
Copy link
Contributor Author

vladfaust commented Sep 11, 2018

I've found a solution:

require "uri"

class Array(T)
  def self.parse(string, type _type : Int32.class)
    return string.split(", ").map { |s| s.to_i }
  end
end

class Array(T)
  def self.parse(string, type _type : Float32.class)
    return string.split(", ").map { |s| s.to_f32 }
  end
end

class Array(T)
  def self.parse(string, type _type : URI.class)
    return string.split(", ").map { |s| URI.parse(s) }
  end
end

pp! Array(Int32).parse("1, 2", type: Int32)
pp! Array(Float32).parse("0.5, 42", type: Float32)
pp! Array(URI).parse("foo, bar", type: URI)

But there is code duplication.

@vladfaust
Copy link
Contributor Author

I'll close this, because it's a specific project question. Any help would be appreciated, though.

@vladfaust
Copy link
Contributor Author

My use-case is related to #3298

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant