[Note: parts of this message were removed to make it a legal post.]
ruby 1.9
(this is about the *abilities* or the ruby 1.9 language)
class Persnon
attrib name String opt1 opt2
attrib age Integer
end
The main questions:
a) Can such an "attrib" method be implemented with ruby code?
b) Can such an "attrib" functionality be implemented on the C-level
(as extension, not as modification of source)?
Any examples?
Please notice the requirements:
1) "name" and not ":name"
2) no comma between "name" and "String" and "opt1" ...
Almost certain this can't be done. You could do something somewhat close to
that, as seen in the below example. But it relies on hacking method_missing
and defining constants as methods which catch their call and store them for
later evaluation, eventually being evaluated when arriving at the attrib
method.
However, you would be susceptible to all the method_missing bugs. In fact,
your example even hit one, because Class.new.respond_to?

name) is true, it
wouldn't hit method_missing. This is why in the example, it must be called
name2. Also, to implement this, you must interfere with the natural flow of
method missing, so if you actually do invoke a missing method anywhere, then
this code will think it is part of a signature for some method you're
passing to attrib.
module ImDoingThisForTheChallengeEvenThoughItsAHorribleIdea
def next_meth_sig
@next_meth_sig ||= []
end
def attrib(signature)
methname, *to_return = signature.reverse
signature.clear
define_method(methname) { to_return }
end
def method_missing(meth, *args, &block)
# when empty, args may be [String], [Integer], etc
# because they get treated as const lookup when doing attrib a Integer
# but get treated as method call when doing attrib a Integer b
return next_meth_sig << meth unless next_meth_sig.empty?
next_meth_sig.concat args << meth
end
[String, Integer].each do |const|
define_method const.to_s do |args|
next_meth_sig << const
end
end
end
require 'rspec'
describe "ImDoingThisForTheChallengeEvenThoughItsAHorribleIdea#attrib" do
before :each do
@class = Class.new do
extend ImDoingThisForTheChallengeEvenThoughItsAHorribleIdea
end
end
context 'when given "attrib name2"' do
before { @class.instance_eval { attrib name2 } }
subject { @class.new }
it { should respond_to :name2 }
its

name2) { should == [] }
end
context 'when given "attrib name2 String"' do
before { @class.instance_eval { attrib name2 String } }
subject { @class.new }
its

name2) { should == [String] }
end
context 'when given "attrib name2 String opt1 opt2"' do
before { @class.instance_eval { attrib name2 String opt1 opt2 } }
subject { @class.new }
it { should respond_to :name2 }
its

name2) { should == [String,

pt1,

pt2] }
end
specify '"attrib age Integer" should define #age which returns [Integer]'
do
@class.instance_eval { attrib age Integer }
@class.new.age.should == [Integer]
end
it "should work with Illias' example" do
class Persnon
extend ImDoingThisForTheChallengeEvenThoughItsAHorribleIdea
attrib name2 String opt1 opt2
attrib age Integer
end
p = Persnon.new
p.name2.should == [String,

pt1,

pt2]
p.age.should == [Integer]
end
end