Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reflection in ruby?

Tags:

ruby

I am curious how this works. For example if I create a factory pattern based class where you can "register" classes for later use and then do something like

FactoryClass.register('YourClassName', [param, param, ...]);
FactoryClass.create('your_class_name').call_method_from_this_object

where 'class_name' is a key in a hash that maps to value: ClassName

is there anything like php reflection, where I can create an instance of a class based on a string name and pass in the arguments in? (in php the arguments would be an array of them that php then knows how what to do with)

So if we take a real world example:

class Foo
  attr_reader :something

  def initialize(input)
    @something = input
  end

  def get_something
    return @something
  end
end

# In the factory class, foo is then placed in a hash: {'foo' => 'Foo'}
# This step might not be required??
FactoryClass.create('Foo', ['hello'])

# Some where in your code:
FactoryClass.create('foo').get_something # => hello

Is this possible to do in ruby? I know everything is essentially an object, but I haven't seen any API or docs on creating class instances from string names like this and also passing in objects.

As for the hash above, thinking about it now I would probably have to do something like:

{'foo' => {'class' => 'Foo', 'params' => [param, param, ...]}}

This way when you call .create on the FactoryClass it would know, ok I can instantiate Foo with the associated params.

If I am way off base, please feel free to educate me.

like image 935
TheWebs Avatar asked May 12 '15 13:05

TheWebs


People also ask

What is the use of reflection API?

Reflection API in Java is used to manipulate class and its members which include fields, methods, constructor, etc. at runtime. One advantage of reflection API in Java is, it can manipulate private members of the class too.

What is metaprogramming in Ruby?

Metaprogramming is a technique by which you can write code that writes code by itself dynamically at runtime. This means you can define methods and classes during runtime.

What is reflection java?

Reflection is a feature in the Java programming language. It allows an executing Java program to examine or "introspect" upon itself, and manipulate internal properties of the program. For example, it's possible for a Java class to obtain the names of all its members and display them.


2 Answers

Check out Module#const_get (retrieving a constant from a String) and Object#send (calling a method from a String).

like image 146
Logan Serman Avatar answered Nov 08 '22 19:11

Logan Serman


Here is an answer that doesn't use eval.

PHP's Reflection is called Metaprogramming in Ruby, but they are quite different. Everything in Ruby is open and could be accessed.

Consider the following code:

class Foo
  attr_reader :something

  def initialize(input)
    @something = input
  end

  def get_something
    return @something
  end
end

@registered = { }
def register(reference_name, class_name, params=[])
  @registered[reference_name] = { class_name: class_name, params: [params].flatten }
end

def create(reference_name)
  h = @registered[reference_name]
  Object.const_get(h[:class_name]).new(*(h[:params]))
end

register('foo', 'Foo', ['something'])
puts create('foo').get_something

You can use Object#const_get to get objects from strings. Object.const_get('Foo') will give you the object Foo.

However, you don't need to send class name as string. You can also pass around the class name as object and use that directly.

class Foo
  attr_reader :something

  def initialize(input)
    @something = input
  end

  def get_something
    return @something
  end
end

@registered = { }
def register(reference_name, class_name, params=[])
  @registered[reference_name] = { class_name: class_name, params: [params].flatten }
end

def create(reference_name)
  h = @registered[reference_name]
  h[:class_name].new(*(h[:params]))
end

register('foo', Foo, ['something else'])
puts create('foo').get_something
like image 34
Harsh Gupta Avatar answered Nov 08 '22 20:11

Harsh Gupta