Local variable output is not being shown - ruby

I am trying to run a simple program:
class Pras
def samleMethod
a = 12
p "a"
end
end
There are no errors, but why is not output being shown?
Edit
class Pras
def samleMethod
a = 12
p a
end
end

class Pras
def samleMethod
a = 12
p a
end
end
In this you are creating a class named Pras with public method named sampleMethod.
I assume you have some knowledge with OOP
so when ever you are accessing a a method you need to create an instance of class to access it.
p = Pras.new
Now you can access the method using the instance
p.sampleMethod
or both in one line as
Pras.new.sampleMethod
I would suggest you to have a through look at this tuts. http://www.tutorialspoint.com/ruby/ruby_quick_guide.htm
methods will not be executed unless they are called.
Try this code online here

You are printing the string 'a' rather than the variable. Use this instead: p a
Edit:
As Rostyslav mentioned, you are not executing anything: Try Pras.new.samleMethod

Works perfectly for me:
Here we define class:
irb(main):014:0> class Pras
irb(main):015:1> def samleMethod
irb(main):016:2> a = 12
irb(main):017:2> p a
irb(main):018:2> end
irb(main):019:1> end
=> nil
Here's how to create and instance object of that class and call instance method with actually do printing:
irb(main):020:0> Pras.new.samleMethod
12
=> 12

Related

How to call another classes methods from another class?

I have the following structure
class A
def method1
end
end
class B
#my = A.new
def classATest
#myT.method1
end
def newTest
classATest
end
end
class C
newB = B.new
newB.newTest
end
When I run class C, it gives me the error that it cannot find method1 of Class A (method newtest, calls method classATest, which calls the method1 using a global variable. What am I doing wrong? Is this not allowed?
Your line that says #my = A.new is not doing anything useful. It's making a new object and assigning it as an instance variable of class B, but that kind of variable cannot be used by instances of B without extra effort. You should replace that line with:
def initialize
#myT = A.new
end
Also, you had a typo: you wrote #my in one place and #myT in another.
Alternatively, keep the code the way you have it and replace #my and #myT with the name of a constant, such as MyA. Constants in Ruby start with capital letters, and can be used the way you are trying to use this variable.

`initialize` seems to check the arguments given to `new`

I am looking at this code:
class Mo
def new(indy, rome = 1)
initialize(indy, rome)
end
def initialize(indy, rome)
...
end
end
Mo.new(2)
I get this output:
test.rb:6:in `initialize': wrong number of arguments (1 for 2) (ArgumentError)
If I add the default value for rome in the definition to new, it works:
class Mo
def new(indy, rome = 1)
initialize(indy, rome)
end
def initialize(indy, rome = 1)
...
end
end
Mo.new(2)
Why?
Because Mo.new(2) calls the method Mo.new, which by default calls the method Mo#initialize with the single argument 2 that it received, but your Mo#initialize expects two arguments.
No need for new method, because initialize is "middleware" for allocating (creating) ruby object
class Mo
def initialize(indy, rome = 1)
#indy = indy
#rome = rome
end
end
i = Mo.new(2)
This means ruby does not enter in new method
You can check it by:
puts Mo.method(:new).source_location
# => nil
but you are able to override self.new in you Mo class
def self.new(indy, rome = 1)
end
then
p Mo.method(:new).source_location
# =>["mo.rb", 2]
And it does not enter in initialize method then
P.S.
It's not good practice, but if you want to execute you code, you should call
Mo.new(2).new(3)
because your new is Mo instance method
When you write a code like
Class Foo
def new
...
end
end
You define an instance method for the object with class Foo. But when you create a new instance, you call a class' method new. If you want to rewrite method Foo.new, you should write like:
Class Foo
def self.new
....
end
end
But actually it is a bad idea to declare your own method new for classes

How to Initialize Class Arrays in Ruby

I want to create an empty array as a class instance variable in Ruby. However, my current method does not seem to work.
Here is my code:
class Something
#something = []
def dosomething
s = 5
#something << s
end
end
When I call the function, it gives me an undefined method traceback.
However, if I do something similar with class variables, i.e.:
class Something
##something = []
def dosomething
s = 5
##something << s
end
end
This works perfectly.
I know I can use the initialize method to actually create an empty list for #something, but is there another way of doing this without using the initialize method? And why does this work for class variables?
EDIT: Fixed typo
You need to use initialize as a constructor as below code and is there any reason why not to use initialize/constructor. And please fix a typo error in class definition Class Something to class Something no camel case or first letter capitalize while in class
class Something
def initialize
#something = Array.new
end
def dosomething
s = 5
#something << s
end
end
class variable ## are available to the whole class scope. so they are working in the code and if you want to use instance variable # you need to initialize it as above. The instance variable is share with instance/objects of a class
for more details visit the link Ruby initialize method
At first you have a typo. Change Classto class. Next I suggest to use the initialize method. While creating a new object this is the perfect place to initialize instance variables.
class Something
##my_class_variable = [1]
def initialize
#something = []
end
def dosomething
s = 5
#something << s
end
def self.get_my_class_variable
##my_class_variable
end
end
Your script will be read and executed from top to bottom and after this,
you can access the class Something. While the parser reads your script/class/module you can define class variables (##), execute mixins and extend the class with other modules. This is why you can define a class variable, but you can not define an instance variable. Because actually you have no instance object from your class. You only have a class object. In ruby everything is an object. And your class object has a defined class variable now:
Something.get_my_class_variable
# => [1]
Now you can create an instance from your class. With Something.new the initialize method will be invoked and your instance variable will be defined.
something = Something.new
something.dosomething
# => [5]
Later, if you are familar with this you can define getter and setter methods with attr_reader, attr_writer and attr_accessor for instance objects or cattr_reader, cattr_writer and cattr_accessor for class objects. For example:
class Something
attr_reader :my_something
def initialize
#my_something = []
end
def dosomething
s = 5
#my_something << s
end
end
something = Something.new
something.my_something
# => []
something.dosomething
# => [5]
something.my_something
# => [5]
Your problem in trying to access #something in your instance method is that, in the scope of instance methods, # variables refer to instance variables, and your #something is a class instance variable.
# variables are instance variables of the instance that is self when they are created. When #something was created, self was the class Something, not an instance of Something, which would be the case inside an instance method.
How then to access a class instance variable in an instance method? Like regular instance variables, this must be done via a method, as in attr_accessor. One way to do this is to use class << self to tell the Ruby interpreter that the enclosed code should be evaluated with the class (and not the instance) as self:
class C
#foo = 'hello'
class << self
attr_accessor :foo # this will be a class method
end
def test_foo # this is, of course, an instance method
puts self.class.foo # or puts C.foo
end
end
We can show that this works in irb:
2.3.0 :005 > C.foo
=> "hello"
2.3.0 :006 > C.new.test_foo
hello
You have correctly created a class instance variable, #something, and initialized it to an empty array. There are two ways for instances to obtain or change the value of that variable. One is to use the methods Object#instance_variable_get and Object#instance_variable_set (invoked on the class):
class Something
#something = []
def dosomething
s = 5
self.class.instance_variable_get(:#something) << s
end
end
sthg = Something.new
sthg.dosomething
Something.instance_variable_get(:#something)
#=> 5
The other way is to create an accessor for the variable. There are several ways to do that. My preference is the following:
Something.singleton_class.send(:attr_accessor, :something)
Something.something #=> [5]
In your dosomething method you would write:
self.class.something << s

Why can't I puts an instance variable of a Ruby class if it contains the value of a variable in a module?

When I try to run this code, nothing or nil shows up. I can't seem to understand why, since I thought classes that include modules can access its instance/class variables. I can print out the value just fine if I don't use garbtest and just use the garb= method to assign it a different value. It works fine without assigning it another value since I initialized it to 16 too. Is there something about the instance/class variables in the module Test that makes it equal to nil? Furthermore, when I try to assign garb to #myg + ##vit it says there is no such method for the nil class. I think this further confirms my suspicion that those variables are somehow nil. Thank you.
module Test
RED = "rose"
BLUE = "ivy"
#myg = 9
##vit = 24.6
end
class Xy
include Test;
def initialize(n)
#garb = n
end
attr_accessor :garb;
def garbTest
#garb = #myg;
end
def exo
return 50;
end
end
ryu = Xy.new(16);
ryu.garbTest;
puts "#{ryu.garb}";
Because #myg is not shared variable. It is private property of module Test, thus while you included Test, #myg didn't come into Xy due to the mixin, it wouldn't come also by default. But, "Why nil?" - Because, instance variable, class variables are like that. Before initialising/defining them, if you attempt to use them, it will simply give you nil.
Small program to prove myself and Ruby :-
module Test
#x = 10
##y = 11
end
class Foo
include Test
end
Foo.instance_variable_defined?(:#x) # => false
Test.instance_variable_defined?(:#x) # => true
Foo.class_variable_defined?(:##y) # => true
Test.class_variable_defined?(:##y) # => true
You can define reader method inside Test singleton class, and then you can use it. Look below
module Test
class << self
attr_reader :myg
end
RED = "rose"
BLUE = "ivy"
#myg = 9
##vit = 24.6
end
class Xy
include Test
def initialize(n)
#garb = n
end
attr_accessor :garb
def garbTest
#garb = Test.myg
end
def exo
return 50
end
end
ryu = Xy.new(16)
ryu.garbTest # => 9

Change the binding of a Proc in Ruby

I have this code:
l = lambda { a }
def some_function
a = 1
end
I just want to access a by the lambda and a special scope which has defined a already somewhere like inside some_function in the example, or just soon later in the same scope as:
l = lambda { a }
a = 1
l.call
Then I found when calling l, it is still using its own binding but not the new one where it was called.
And then I tried to use it as:
l.instance_eval do
a = 1
call
end
But this also failed, it is strange that I can't explain why.
I know the one of the solution is using eval, in which I could special a binding and executing some code in text, but I really do not want to use as so.
And, I know it is able to use a global variable or instance variable. However, actually my code is in a deeper embedded environment, so I don't want to break the completed parts if not quite necessary.
I have referred the Proc class in the documentation, and I found a function names binding that referred to the Proc's context. While the function only provided a way to access its binding but cannot change it, except using Binding#eval. It evaluate text also, which is exactly what I don't like to do.
Now the question is, do I have a better (or more elegant) way to implement this? Or using eval is already the regular manner?
Edit to reply to #Andrew:
Okay, this is a problem which I met when I'm writing a lexical parser, in which I defined a array with fixed-number of items, there including at least a Proc and a regular expression. My purpose is to matching the regular expressions and execute the Procs under my special scope, where the Proce will involved some local variables that should be defined later. And then I met the problem above.
Actually I suppose it is not same completely to that question, as mine is how to pass in binding to a Proc rather than how to pass it out.
#Niklas:
Got your answer, I think that is what exactly I want. It has solved my problem perfectly.
You can try the following hack:
class Proc
def call_with_vars(vars, *args)
Struct.new(*vars.keys).new(*vars.values).instance_exec(*args, &self)
end
end
To be used like this:
irb(main):001:0* lambda { foo }.call_with_vars(:foo => 3)
=> 3
irb(main):002:0> lambda { |a| foo + a }.call_with_vars({:foo => 3}, 1)
=> 4
This is not a very general solution, though. It would be better if we could give it Binding instance instead of a Hash and do the following:
l = lambda { |a| foo + a }
foo = 3
l.call_with_binding(binding, 1) # => 4
Using the following, more complex hack, this exact behaviour can be achieved:
class LookupStack
def initialize(bindings = [])
#bindings = bindings
end
def method_missing(m, *args)
#bindings.reverse_each do |bind|
begin
method = eval("method(%s)" % m.inspect, bind)
rescue NameError
else
return method.call(*args)
end
begin
value = eval(m.to_s, bind)
return value
rescue NameError
end
end
raise NoMethodError
end
def push_binding(bind)
#bindings.push bind
end
def push_instance(obj)
#bindings.push obj.instance_eval { binding }
end
def push_hash(vars)
push_instance Struct.new(*vars.keys).new(*vars.values)
end
def run_proc(p, *args)
instance_exec(*args, &p)
end
end
class Proc
def call_with_binding(bind, *args)
LookupStack.new([bind]).run_proc(self, *args)
end
end
Basically we define ourselves a manual name lookup stack and instance_exec our proc against it. This is a very flexible mechanism. It not only enables the implementation of call_with_binding, it can also be used to build up much more complex lookup chains:
l = lambda { |a| local + func(2) + some_method(1) + var + a }
local = 1
def func(x) x end
class Foo < Struct.new(:add)
def some_method(x) x + add end
end
stack = LookupStack.new
stack.push_binding(binding)
stack.push_instance(Foo.new(2))
stack.push_hash(:var => 4)
p stack.run_proc(l, 5)
This prints 15, as expected :)
UPDATE: Code is now also available at Github. I use this for one my projects too now.
class Proc
def call_with_obj(obj, *args)
m = nil
p = self
Object.class_eval do
define_method :a_temp_method_name, &p
m = instance_method :a_temp_method_name; remove_method :a_temp_method_name
end
m.bind(obj).call(*args)
end
end
And then use it as:
class Foo
def bar
"bar"
end
end
p = Proc.new { bar }
bar = "baz"
p.call_with_obj(self) # => baz
p.call_with_obj(Foo.new) # => bar
Perhaps you don't actually need to define a later, but instead only need to set it later.
Or (as below), perhaps you don't actually need a to be a local variable (which itself references an array). Instead, perhaps you can usefully employ a class variable, such as ##a. This works for me, by printing "1":
class SomeClass
def l
#l ||= lambda { puts ##a }
end
def some_function
##a = 1
l.call
end
end
SomeClass.new.some_function
a similar way:
class Context
attr_reader :_previous, :_arguments
def initialize(_previous, _arguments)
#_previous = _previous
#_arguments = _arguments
end
end
def _code_def(_previous, _arguments = [], &_block)
define_method("_code_#{_previous}") do |_method_previous, _method_arguments = []|
Context.new(_method_previous, _method_arguments).instance_eval(&_block)
end
end
_code_def('something') do
puts _previous
puts _arguments
end

Resources