Class instance with names defined by string

instance variable
instance variable java
instance method
constructor in java
class in java
class variable
instance method java
classes and methods in java

In 'pure ruby' (not rails), given a class:

class Person
end

...and an array of strings:

people_names = ['John', 'Jane', 'Barbara', 'Bob']

how can I instantiate the Person class, with each instance variable named one of the elements in my array?

John = Person.new
Jane = Person.new
Barbara = Person.new
Bob = Person.new

Its pretty unclear what you actually want here since an identifier in ruby starting with an uppercase letter in Ruby is a constant.

John = Person.new
Jane = Person.new
Barbara = Person.new
Bob = Person.new

You can dynamically assign constants with Module#const_set.

module MyModule
  ['John', 'Jane', 'Barbara', 'Bob'].each do |name|
    const_set(name, Person.new)
  end
end

# this imports the constants into Main which is the global scope
include MyModule

John
=> #<Person:0x007f973586a618>

Instance variables on the other hand use the @ sigil. You can dynamically assign instance variables with instance_variable_set:

['John', 'Jane', 'Barbara', 'Bob'].map(&:downcase).each do |name|
  instance_variable_set("@#{name}", Person.new)
end

@john       
# => #<Person:0x007f9734089530>

While you can declare an instance variable named @John it violates the conventions of the language.

Local variables cannot actually be defined dynamically. You can only change existing variables via eval and binding.local_variable_set.

def foo
  a = 1
  bind = binding
  bind.local_variable_set(:a, 2) # set existing local variable `a'
  bind.local_variable_set(:b, 3) # create new local variable `b'
                                 # `b' exists only in binding

  p bind.local_variable_get(:a)  #=> 2
  p bind.local_variable_get(:b)  #=> 3
  p a                            #=> 2
  p b                            #=> NameError
end

Creating and Using Classes and Methods, The string identifier is both the internal class name and the name of the A scope refers to the methods and object variables defined for a single class (not  This means that for each object or instance of a class, the instance variables are different. Unlike class variables, instance variables are defined within methods. In the Shark class example below, name and age are instance variables: class Shark: def __init__(self, name, age): self.name = name self.age = age


I'm sure Ruby has some means for you into defining constants dynamically, but I'm not going to bother looking that up because this feels, almost 100%, like something you don't really want to do. It seems like you want some way to associate a "name" to a class instance. That is exactly what Hash is for.

people_names = ['John', 'Jane', 'Barbara', 'Bob']
people = people_names.each_with_object({}) do |name, ppl|
  ppl[name] = Person.new(name)
end
people['John'].name # => 'John'
people['Jane'].name # => 'Jane'

Why do I say what you're asking for is probably not what you want? Because use meta programming to dynamically create and dynamically read from local variables/constants/instance variables is just generally frowned upon in professional development. For your own projects, for experimentation, sure maybe. For any project as part of a team though, when you start using meta-programming features to dynamically add these values and reference them (maybe directly, maybe indirectly later) is all well and good but when you try and figure out what's going on you will almost never be able to figure out where these things are defined/coming from unless the array with the dynamic names is hard coded. And if it's hard-coded why can't you just build the constants/variables/targets directly in the code? That's significantly better than dynamically doing it.

# this is a fake API to demonstrate
# let's assume this is what you want
PEOPLE_NAMES = ['John', 'Jane']
PEOPLE_NAMES.each do |name|
  const_def(name, Person.new)
end

get_person('Jane').do_something # maps to const_get('Jane').do_something
get_person(PEOPLE_NAMES[0]).do_something
John.do_something

If you want the above, why can't you just do:

John = Person.new
Jane = Person.new

John.do_something

The latter is loads more clear, can still be dynamically looked up, but has a hardcoded definition that can easily be targeted when debugging.

That's my recommendation and answer. I'm pretty sure you don't want to do what you're asking to do. Hash totally fits the needs you desire, it's used heavily for purposes like this and closely related to it, I recommend you try and make that work for your needs then try and figure how to solve the problem you're specifically looking to get an answer too.

EDIT

As a really fun add-on, you can do some really cool dynamic stuff with Hash here that doesn't lead to tons of confusion unless you happen to hide where the hash is coming from. But you could do something like:

people = Hash.new { |h, k| h[k] = Person.new(k) }
# right now, people contains no actual people
people['John'].name # => 'John'
# now people contains one Person instance

This is cool for two reasons 1) You don't have to have a list to generate the hash, so if you get names after hash creation that's fine you can just add them by accessing that users name and 2) Being lazy, it will only use the memory you need. If you preload the hash with all four persons, and then access data from only two persons you wasted the space required for the unused 2 Person instances, so this let's you use only as much as you need and otherwise offers you all the same benefits.

Understanding Class Members (The Java™ Tutorials > Learning the , In the case of the Bicycle class, the instance variables are cadence , gear , and speed For example, the following variable declaration defines a constant named PI Note: If a primitive type or a string is defined as a constant and the value is  Define a public class called Account that i. has an instance variable called name of type String ii. has an instance variable called balance of type double ii. defines a constructor that takes two parameters used to set the instance variables name and balance Define a subclass of Account called InterestAccount that


You can certainly do it, although as Brandon says it probably isn't a good idea. Here's how to do it:

people_names.each { |name| eval("#{name} = Person.new")}

eval takes a string passed as an argument and executes it as a line of code. So, you use each to do that once for each member of your array.

You might want to google "eval" to see any number of articles about why it's evil. Many of these go off on metaprogramming (eval is an example of metaprogramming) in general, and make some good points. I have a bit more moderate approach to metaprogramming than that (attr_accessor, after all, is an example of metaprogramming, too, and people use it all the time), but you can certainly write some very tangled code using eval.

Note also, as several posters have observed, that by capitalizing your strings you are defining them as constants. You can change a constant's value in Ruby, but you will get a warning every time you do so.

Javanotes 8.1, Answers for Quiz on Chapter 5, That is, the class contains the source code that defines instance variables and public class Player { private String name; private int score; public String  If I have the name in a string of one of the framework's core classes (such as "System.Collections.ArrayList"), what's the easiest way for me to create an instance of the appropriate class? In VB6 I would have simply used CreateObject, is there an equally simple way in VB.NET? Thanks,--(O)enone


Javanotes 8.1, Section 5.1 -- Objects, Instance Methods, and , If an object is also a collection of variables and methods, how do We just left the word "static" out of the subroutine definitions! class UserData { static String name; static int age; }. As the name implies, public instance methods are methods available on class instances. class ClassWithPublicInstanceMethod { publicMethod() { return 'hello world' } } const instance = new ClassWithPublicInstanceMethod() console.log(instance.publicMethod()) // expected output: "hello worl d" Public instance methods are added to the class


Object orientation, Classes do not need to have the same base name as their source file definitions but it is highly recommended in most  Python isinstance() to check whether the object is an instance of the specified class type. isinstance() function to check instance with the String type, number type, dict type, list type.isinstance() with Python Class and inheritance


Defining and using a class, If our attribute name is stored as a string value in a variable, we have to use the getattr function to retrieve the attribute value from an object: for key in ["a", "b",  Public instance methods are added to the class prototype at the time of class evaluation using Object.defineProperty(). They are writable, non-enumerable, and configurable. You may make use of generator, async, and async generator functions. class ClassWithFancyMethods { *generatorMethod() { } async asyncMethod() { } async *asyncGeneratorMethod