hi, i wrote a small code to check metaprogramming in ruby..what am i doing wrong..can you pl help?
class Testvar attr_accessor :a1 def initialize @a1='init' end end
var =":a1"
t = Testvar.new if t.respond_to?("#{var}") p 'test 1- pass' end if t.instance_variable_set var , 'abc' p 'test 2-pass' end if t.send var , 'def' p 'test 3-pass' end
> hi, i wrote a small code to check metaprogramming in ruby..what am i > doing wrong..can you pl help?
> class Testvar > attr_accessor :a1 > def initialize > @a1='init' > end > end
> var =":a1"
> t = Testvar.new > if t.respond_to?("#{var}") > p 'test 1- pass' > end > if t.instance_variable_set var , 'abc' > p 'test 2-pass' > end > if t.send var , 'def' > p 'test 3-pass' > end
What did you expect it to do, and what did it actually do? I'm guessing that it blows up at instance_variable_set, because a1 is not a valid ivar name. Try with an @ instead:
On Thu, Nov 12, 2009 at 6:05 PM, Dhaval <dhavalvtha...@gmail.com> wrote: > hi, i wrote a small code to check metaprogramming in ruby..what am i > doing wrong..can you pl help?
> class Testvar > attr_accessor :a1 > def initialize > @a1='init' > end > end
> var =":a1"
> t = Testvar.new > if t.respond_to?("#{var}") > p 'test 1- pass' > end > if t.instance_variable_set var , 'abc' > p 'test 2-pass' > end > if t.send var , 'def' > p 'test 3-pass' > end
Try like this:
class Testvar attr_accessor :a1 def initialize @a1='init' end end
var = :a1
t = Testvar.new
if t.respond_to?(var) puts 'test 1- pass' end
t.instance_variable_set "@#{var}" , 'abc' if t.instance_variable_get("@#{var}") == 'abc' puts 'test 2-pass' end
t.send "#{var}=" , 'def' if t.send(var) == 'def' puts 'test 3-pass' end
Then search for "respond_to?" and you will see three classes which define it, in the frame on the far right, which lists methods. The three you will see are:
> t = Testvar.new > if t.respond_to?("#{var}") > p 'test 1- pass' > end
Here you are testing if your object has a particular method. The method name is "a1". You can either pass the string "a1" or the symbol :a1
However you passed the string ":a1" consisting of three characters - colon, a, 1.
> if t.instance_variable_set var , 'abc' > p 'test 2-pass' > end
Here you are talking about an instance variable, not a method. The instance variable's name is "@a1". You can either pass the string "@a1" or the symbol :@a1
> if t.send var , 'def' > p 'test 3-pass' > end
Here you're trying to call a setter method. The method's name is "a1=". Again, you can either pass the string "a1=" or the symbol :a1= -- Posted via http://www.ruby-forum.com/.