Some help please for a relative newcomer to Ruby, though not to programming. I have some code designed to manage lists of objects. These include the following methods :-
def initialize
super @things = Array.new
end
def loadData(filename)
input_data = File.read(filename) @things = YAML::load(input_data)
end
These work fine, for my pupose. However, if I attemp to combine these thus :-
#This does not work
def createFromFile(aFilename)
initialize
loadData(aFilename)
end
Gives error message as follows :-
UdateAssets.rb:7:in `<main>': undefined method `createFromFile' for ZSAssets:Class (NoMethodError)
Calling code snippets :-
assets = ZSAssets.new() #New AssetList
assets.loadData('assets2.yml')
assets[0].displayData
works fine
assets = ZSAssets.createFromFile('assets2.yml')
assets[0].displayData
gives the error, even though the method IS clearly defined and present. Any ideas what the problem is?
I appreciate that using the two methods separately is not a major problem, but, like most coders would rather use one line than two every time.
Many thanks in advance. I hope I have included enough information.
If you want to use the other way...
assets = ZSAssets.createFromFile('assets2.yml')
... you will have to define a 'class method' on ZSAssets class.
Hope it helps!
Abinoam Jr.
···
Em dom, 7 de jun de 2015 às 23:33, Patrick Bayford <pbayford@talktalk.net> escreveu:
Some help please for a relative newcomer to Ruby, though not to
programming. I have some code designed to manage lists of objects. These
include the following methods :-
def initialize
super @things = Array.new
end
def loadData(filename)
input_data = File.read(filename) @things = YAML::load(input_data)
end
These work fine, for my pupose. However, if I attemp to combine these thus
:-
#This does not work
def createFromFile(aFilename)
initialize
loadData(aFilename)
end
Gives error message as follows :-
UdateAssets.rb:7:in `<main>': undefined method `createFromFile' for
ZSAssets:Class (NoMethodError)
Calling code snippets :-
assets = ZSAssets.new() #New AssetList
assets.loadData('assets2.yml')
assets[0].displayData
works fine
assets = ZSAssets.createFromFile('assets2.yml')
assets[0].displayData
gives the error, even though the method IS clearly defined and present.
Any ideas what the problem is?
I appreciate that using the two methods separately is not a major problem,
but, like most coders would rather use one line than two every time.
Many thanks in advance. I hope I have included enough information.
--
Patrick Bayford Tel : 020 8265 8376 E-mail : pbayford@talktalk.net
No virus found in this message.
Checked by AVG - www.avg.com
Version: 2015.0.5961 / Virus Database: 4355/9970 - Release Date: 06/07/15
#This does not work
def createFromFile(aFilename)
initialize
loadData(aFilename)
end
Here you are creating an instance method (I'm assuming it's within a
class).
Gives error message as follows :-
UdateAssets.rb:7:in `<main>': undefined method `createFromFile' for
ZSAssets:Class (NoMethodError)
Here it seems you're calling a class, rather than instance, method.
Calling code snippets :-
assets = ZSAssets.new() #New AssetList
assets.loadData('assets2.yml')
assets[0].displayData
works fine
assets = ZSAssets.createFromFile('assets2.yml')
And in the code you're doing it wrong. ZSAssets.createFromFile is
expecting a class method:
class ZSAssets
def self.createFromFile(aFilename)
end
end
but you defined an *instance* method. If you want to create a factory
method you need to do the "def self.createFromFile" definition in my
comment above and then working with a local instance of your ZSAssets
class in that method.
<snip>
···
On Mon, Jun 08, 2015 at 03:33:38AM +0100, Patrick Bayford wrote:
--
Darryl L. Pierce <mcpierce@gmail.com>
Famous last words:
"I wonder what happens if we do it this way?"
One probable issue with your code is that the initialize method is always private so you cannot call it directly as you have done:
irb(main):001:0> class Sample
irb(main):002:1> def initialize
irb(main):003:2> @i = 1
irb(main):004:2> end
irb(main):005:1> end
=> :initialize
irb(main):007:0> Sample.initialize
NoMethodError: private method `initialize' called for Sample:Class
from (irb):7
from /usr/local/bin/irb:11:in `<main>'
As I understand, the initialize method does not actually create an object, it is called once the object has been created.
Hope this helps.
Peter
···
On 8 Jun 2015, at 10:33, Patrick Bayford <pbayford@talktalk.net> wrote:
Some help please for a relative newcomer to Ruby, though not to programming. I have some code designed to manage lists of objects. These include the following methods :-
def initialize
super @things = Array.new
end
def loadData(filename)
input_data = File.read(filename) @things = YAML::load(input_data)
end
These work fine, for my pupose. However, if I attemp to combine these thus :-
#This does not work
def createFromFile(aFilename)
initialize
loadData(aFilename)
end
Gives error message as follows :-
UdateAssets.rb:7:in `<main>': undefined method `createFromFile' for ZSAssets:Class (NoMethodError)
Calling code snippets :-
assets = ZSAssets.new() #New AssetList
assets.loadData('assets2.yml')
assets[0].displayData
works fine
assets = ZSAssets.createFromFile('assets2.yml')
assets[0].displayData
gives the error, even though the method IS clearly defined and present. Any ideas what the problem is?
I appreciate that using the two methods separately is not a major problem, but, like most coders would rather use one line than two every time.
Many thanks in advance. I hope I have included enough information.
It is true that `initialize` is private by default because it is the first
method that gets called when the object is created, more or less the
constructor of other languages.
However, it is just a method and *can* be called from the object, since its
just a private method:
[1] pry(main)> class MySample
[1] pry(main)* def initialize
[1] pry(main)* puts "In init"
[1] pry(main)* end
[1] pry(main)* def foo
[1] pry(main)* initialize
[1] pry(main)* end
[1] pry(main)* end
=> :foo
[2] pry(main)> m = MySample.new
In init
=> #<MySample:0x00000000ea15a0>
[3] pry(main)> m.foo
In init
=> nil
But I would advise against calling `initialize` explicitly. Perhaps Patrick
wanted to create a general "init" or "setup" method and chose `initialize` by
accident.
Even though `createFromFile` becomes superflous then, it should still be
possible to actually call it. Patrick, can you post the complete example
including your class definition, please?
--- Eric
···
On Monday 08 June 2015 11:41:59, Peter W A Wood <peterwawood@gmail.com> wrote:
One probable issue with your code is that the initialize method is always
private so you cannot call it directly as you have done:
[...]
As I understand, the initialize method does not actually create an object,
it is called once the object has been created.
If you want a method like createFromFile (create_from_file or even
from_file :)) to be a kind of alternative constructor, it is better
declared as a class method, as Abinoam explained:
2.0.0-p195 :001 > class ZSAssets
2.0.0-p195 :002?> def initialize a,b,c
2.0.0-p195 :003?> @a, @b, @c = a, b, c
2.0.0-p195 :004?> end
2.0.0-p195 :005?> def self.from_file filename, *args
2.0.0-p195 :006?> instance = new *args
2.0.0-p195 :007?> instance.loadData(filename)
2.0.0-p195 :008?> instance
2.0.0-p195 :009?> end
2.0.0-p195 :010?> def loadData(filename)
2.0.0-p195 :011?> @filename = filename
2.0.0-p195 :012?> end
2.0.0-p195 :013?> end
=> nil
2.0.0-p195 :014 > a = ZSAssets.from_file "myfile", 1,2,3
=> #<ZSAssets:0x00000001e54150 @a=1, @b=2, @c=3, @filename="myfile">
2.0.0-p195 :015 > a
=> #<ZSAssets:0x00000001e54150 @a=1, @b=2, @c=3, @filename="myfile">
Hope this helps,
Jesus.
···
On Mon, Jun 8, 2015 at 1:19 PM, Eric MSP Veith <eveith@wwweb-library.net> wrote:
On Monday 08 June 2015 11:41:59, Peter W A Wood <peterwawood@gmail.com> wrote:
One probable issue with your code is that the initialize method is always
private so you cannot call it directly as you have done:
[...]
As I understand, the initialize method does not actually create an object,
it is called once the object has been created.
It is true that `initialize` is private by default because it is the first
method that gets called when the object is created, more or less the
constructor of other languages.
However, it is just a method and *can* be called from the object, since its
just a private method:
[1] pry(main)> class MySample
[1] pry(main)* def initialize
[1] pry(main)* puts "In init"
[1] pry(main)* end
[1] pry(main)* def foo
[1] pry(main)* initialize
[1] pry(main)* end
[1] pry(main)* end
=> :foo
[2] pry(main)> m = MySample.new
In init
=> #<MySample:0x00000000ea15a0>
[3] pry(main)> m.foo
In init
=> nil
But I would advise against calling `initialize` explicitly. Perhaps Patrick
wanted to create a general "init" or "setup" method and chose `initialize` by
accident.
Even though `createFromFile` becomes superflous then, it should still be
possible to actually call it. Patrick, can you post the complete example
including your class definition, please?
Thanks for the response Eric, (and all the others). Should have spotted the need for a class method here, silly me! Full class definition attached. In fact, the solution proposed by Abinoam Jr works fine (line 4 of the calling code).
Will work on class methods further. (My background is latterly all Object Pascal (Delphi), where these would all be "constructors"), however, data serialising is NOT fun in OP!!
On Monday 08 June 2015 11:41:59, Peter W A Wood <peterwawood@gmail.com> wrote:
One probable issue with your code is that the initialize method is always
private so you cannot call it directly as you have done:
[...]
As I understand, the initialize method does not actually create an object,
it is called once the object has been created.
It is true that `initialize` is private by default because it is the first
method that gets called when the object is created, more or less the
constructor of other languages.
However, it is just a method and *can* be called from the object, since its
just a private method:
[1] pry(main)> class MySample
[1] pry(main)* def initialize
[1] pry(main)* puts "In init"
[1] pry(main)* end
[1] pry(main)* def foo
[1] pry(main)* initialize
[1] pry(main)* end
[1] pry(main)* end
=> :foo
[2] pry(main)> m = MySample.new
In init
=> #<MySample:0x00000000ea15a0>
[3] pry(main)> m.foo
In init
=> nil
But I would advise against calling `initialize` explicitly. Perhaps Patrick
wanted to create a general "init" or "setup" method and chose `initialize` by
accident.
Even though `createFromFile` becomes superflous then, it should still be
possible to actually call it. Patrick, can you post the complete example
including your class definition, please?
--- Eric
--
Patrick Bayford Tel : 020 8265 8376 E-mail : pbayford@talktalk.net
I have now been able to look at the class method approach, which also works well. I guess that this is probably the "better" way to do the job. Many thanks for all the help and suggestions.
···
On 08/06/2015 9:43 PM, Patrick Bayford wrote:
On 08/06/2015 12:19 PM, Eric MSP Veith wrote:
On Monday 08 June 2015 11:41:59, Peter W A Wood<peterwawood@gmail.com> wrote:
One probable issue with your code is that the initialize method is always
private so you cannot call it directly as you have done:
[...]
As I understand, the initialize method does not actually create an object,
it is called once the object has been created.
It is true that `initialize` is private by default because it is the first
method that gets called when the object is created, more or less the
constructor of other languages.
However, it is just a method and *can* be called from the object, since its
just a private method:
[1] pry(main)> class MySample
[1] pry(main)* def initialize
[1] pry(main)* puts "In init"
[1] pry(main)* end
[1] pry(main)* def foo
[1] pry(main)* initialize
[1] pry(main)* end
[1] pry(main)* end
=> :foo
[2] pry(main)> m = MySample.new
In init
=> #<MySample:0x00000000ea15a0>
[3] pry(main)> m.foo
In init
=> nil
But I would advise against calling `initialize` explicitly. Perhaps Patrick
wanted to create a general "init" or "setup" method and chose `initialize` by
accident.
Even though `createFromFile` becomes superflous then, it should still be
possible to actually call it. Patrick, can you post the complete example
including your class definition, please?
--- Eric
Thanks for the response Eric, (and all the others). Should have spotted the need for a class method here, silly me! Full class definition attached. In fact, the solution proposed by Abinoam Jr works fine (line 4 of the calling code).
Will work on class methods further. (My background is latterly all Object Pascal (Delphi), where these would all be "constructors"), however, data serialising is NOT fun in OP!!
--
Patrick Bayford Tel : 020 8265 8376 E-mail : pbayford@talktalk.net
No virus found in this message.
Checked by AVG - www.avg.com <http://www.avg.com>
Version: 2015.0.5961 / Virus Database: 4355/9976 - Release Date: 06/08/15
No virus found in this message.
Checked by AVG - www.avg.com <http://www.avg.com>
Version: 2015.0.5961 / Virus Database: 4355/9976 - Release Date: 06/08/15
--
Patrick Bayford Tel : 020 8265 8376 E-mail : pbayford@talktalk.net
-----
No virus found in this message.
Checked by AVG - www.avg.com
Version: 2015.0.5961 / Virus Database: 4355/9991 - Release Date: 06/10/15