How to Access a Class Variable from the Outside in Ruby

How to access variable from outside class in another file

Those are not global variables. They are called "instance variables" and to access them you need to create instances of your casinos and players. Looks like this.

player = Player.new
player.money # => 0
player.money += 10
player.money # => 10

In your Casino class you don't call parent initializers (a simple oversight, I think), so it doesn't initialize @name and @money.

And Roulette doesn't do anything at all to obtain a wallet. So it stays at default value nil.

Access instance variable from outside the class

Yes, you can use instance_variable_get like this:

class Hello
def method1
@hello = "pavan"
end
end

h = Hello.new
p h.instance_variable_get(:@hello) #nil
p h.method1 #"pavan" - initialization of @hello
p h.instance_variable_get(:@hello) #"pavan"

If the variable is undefined (first call of instance_variable_get in my example) you get nil.


As Andrew mention in his comment:

You should not make this the default way you access instance variables as it violates encapsulation.

A better way is to define an accessor:

class Hello
def method1
@hello = "pavan"
end
attr_reader :hello
end

h = Hello.new
p h.hello #nil
p h.method1 #"pavan" - initialization of @hello
p h.hello #"pavan"

If you want another method name, you could alias the accessor: alias :my_hello :hello.

And if the class is not defined in your code, but in a gem: You can modify classes in your code and insert new functions to classes.

Unable to access instance variable outside the class in ruby

In order to print an instance variable, you must access it with the context of the instance.

p @obj.stacks

Access Instance Variables outside class - Ruby

The simple answer here is to add attr_reader which makes these variables accessible:

class BraintreeTransaction::PopulateForm
attr_reader :first_name
attr_reader :last_name

# ...
end

Then you can access these only if you capture the populate module:

def new
@populate = BraintreeTransaction::PopulateForm.new(@user).populate_form
end

In your view you can then use them like this:

<%= text_field_tag :first_name, @populate.first_name, ... %>

I'd recommend doing this lazy-loading style though, to avoid having to manually initialize it:

class BraintreeTransaction::PopulateForm
def initialize(user)
@user = user
end

def first_name
user_details and user_details.first_name
end

def last_name
user_details and user_details.last_name
end

def user_details
@user_details ||=
Transaction.where(
user_id: @user.id,
completed: false
).order(
created_at: :desc
).first
end

This has the effect of cutting your queries in half and caching the result so only the first access has cost. Calling populate_form manually is implicit, no longer required.



Related Topics



Leave a reply



Submit