From: pjb@... (Pascal J. Bourguignon) Date: 2009-05-15T18:50:05+09:00 Subject: Re: Ruby loops and definitions help? Bob Sanders writes: > Hello. I'm looking to construct a loop that defines an array of [apple, > banana, cherry] like this: > > @apple = apple > @banana = banana > @cherry = cherry > > I'm thinking it's something in this form: > > [apple, banana, cherry].each do |attribute| > @*attribute* = attribute > end > > ..but I have no idea what belongs in place of the *attribute*. Does > anyone know? Yes. The objects in ruby do know if and when, how. You must ask them! For example, using ri(1). irb(main):001:0> (ri "Object") ---------------------------------------------------------- Class: Object +Object+ is the parent class of all classes in Ruby. Its methods are therefore available to all objects unless explicitly overridden. +Object+ mixes in the +Kernel+ module, making the built-in kernel functions globally accessible. Although the instance methods of +Object+ are defined by the +Kernel+ module, we have chosen to document them here for clarity. In the descriptions of Object's methods, the parameter _symbol_ refers to a symbol, which is either a quoted string or a +Symbol+ (such as +:name+). ------------------------------------------------------------------------ Includes: --------- Kernel(Array, Float, Integer, Pathname, String, URI, `, abort, at_exit, autoload, autoload?, binding, block_given?, callcc, caller, catch, chomp, chomp!, chop, chop!, eval, exec, exit, exit!, fail, fork, format, getc, gets, global_variables, gsub, gsub!, iterator?, lambda, load, local_variables, loop, method_missing, open, open, open_uri_original_open, p, pp, pretty_inspect, print, printf, proc, putc, puts, raise, rand, readline, readlines, require, scan, scanf, select, set_trace_func, sleep, split, sprintf, srand, sub, sub!, syscall, system, test, throw, trace_var, trap, untrace_var, warn, warn, y), PP::ObjectMixin(pretty_print, pretty_print_cycle, pretty_print_inspect, pretty_print_instance_variables) Constants: ---------- MatchingData: rb_cMatch ENV: envtbl ENV: envtbl TOPLEVEL_BINDING: rb_f_binding(ruby_top_self) STDIN: rb_stdin STDOUT: rb_stdout STDERR: rb_stderr ARGF: argf NIL: Qnil TRUE: Qtrue FALSE: Qfalse DATA: f ARGV: rb_argv RUBY_VERSION: v RUBY_RELEASE_DATE: d RUBY_PLATFORM: p RUBY_PATCHLEVEL: INT2FIX(RUBY_PATCHLEVEL) VERSION: v RELEASE_DATE: d PLATFORM: p IPsocket: rb_cIPSocket TCPsocket: rb_cTCPSocket SOCKSsocket: rb_cSOCKSSocket TCPserver: rb_cTCPServer UDPsocket: rb_cUDPSocket UNIXsocket: rb_cUNIXSocket UNIXserver: rb_cUNIXServer Class methods: -------------- new Instance methods: ----------------- ==, ===, =~, __id__, __send__, class, clone, dclone, display, dup, enum_for, eql?, equal?, extend, freeze, frozen?, hash, id, inspect, instance_eval, instance_of?, instance_variable_get, instance_variable_get, instance_variable_set, instance_variable_set, instance_variables, is_a?, kind_of?, method, methods, nil?, object_id, private_methods, protected_methods, public_methods, remove_instance_variable, respond_to?, send, singleton_method_added, singleton_method_removed, singleton_method_undefined, singleton_methods, taint, tainted?, to_a, to_enum, to_s, to_yaml, to_yaml_properties, to_yaml_style, type, untaint nil irb(main):002:0> (ri "Object.instance_variable_set") ------------------------------------------- Object#instance_variable_set obj.instance_variable_set(symbol, obj) => obj ------------------------------------------------------------------------ Sets the instance variable names by _symbol_ to _object_, thereby frustrating the efforts of the class's author to attempt to provide proper encapsulation. The variable did not have to exist prior to this call. class Fred def initialize(p1, p2) @a, @b = p1, p2 end end fred = Fred.new('cat', 99) fred.instance_variable_set(:@a, 'dog') #=> "dog" fred.instance_variable_set(:@c, 'cat') #=> "cat" fred.inspect #=> "#" nil irb(main):003:0> ( ["apple","banana","cherry"] . each { | attribute | (self . instance_variable_set( (("@" + attribute) . to_sym) , attribute)) } ) ["apple", "banana", "cherry"] irb(main):004:0> @apple "apple" irb(main):005:0> @banana "banana" irb(main):006:0> @cherry "cherry" irb(main):007:0> @pear nil irb(main):008:0> That said, an array like [apple, banana, cherry] will actually be an array such as ["value of apple", 42, ["the",:value,0,"cherry"]]. If you want to build an array containing the name of the variable, then you have to make an array of symbols: [:apple,:banana,:cherry]. Then you will have to write: irb(main):018:0> (begin (apple = "value of apple") (banana = 42) (cherry = ["the",:value,0,"cherry"]) ( [:apple,:banana,:cherry] . each { | variable | (self . instance_variable_set( (("@" + (variable . to_s)) . to_sym) , (eval (variable . to_s)))) }) end) [:apple, :banana, :cherry] irb(main):025:0> @apple "value of apple" irb(main):026:0> @banana 42 irb(main):027:0> @cherry ["the", :value, 0, "cherry"] irb(main):028:0> -- __Pascal Bourguignon__