Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Вызов функции из указателя на класс.


Автор: myth777 30.3.2009, 17:15
У меня есть класс Class1
Есть еще один класс, хранящий массив указателей на Class1
Внем мне приспичило вызвать функцию из этих указателей.

$self->{Mas_mDsGUI}->[$i]->CallFunction();

Вобщем не работает. Как быть?

Автор: ginnie 30.3.2009, 17:19
myth777, я бы, на Вашем месте, написал текст сообщения об ошибке  smile тогда сразу бы посыпались предложения

Автор: myth777 30.3.2009, 17:29
Если вызываю метод
Код

print  $self->{Mas_mDsGUI}->[$i]->PrintOk();

то пишет
Software error:
Can't call method "PrintOk" on unblessed reference at C:/Server/wwwroot/cgi-bin/lib//group_DSGUI.pm line 149.


А вот если я печатаю     
Код

print $self->{Mas_mDsGUI}->[$i]->{Table};

То переменную Table он видит

Автор: ginnie 30.3.2009, 17:38
Цитата(myth777 @  30.3.2009,  17:29 Найти цитируемый пост)
Can't call method "PrintOk" on unblessed reference

означает, что ссылка не является объектом. Как Вы сохраняете объекты в массиве?

Автор: myth777 30.3.2009, 17:46
Я понимаю что не является объектом.
Вот как заполняю.
Код

  push (@{$grDs->{Mas_mDsGUI}} ,   tbl_noid::GetInterphasemDSGUI());
  push (@{$grDs->{Mas_mDsGUI}} ,   noid_info::GetInterphasemDSGUI());



Код

sub  GetInterphasemDSGUI()
{
  my $mgui= mDSGUI->new();
  $mgui->init(\%has);
  return $mgui;
}


В таком случае все переменные класса mDSGUI, хранящиеся в его анонимном хэше видяться а функции нет. Причем если просто создаю класс 

Код

my $mg = mDSGUI->new() 


то из $mg  все нормально будет вызываться и видеться(переменные и функции)
Код

$mg->PrintOk();

будет работать

Добавлено через 3 минуты и 24 секунды
Вот как заполняю переменные mDSGUI
Код


  my $invocant = shift();
  my $class = ref($invocant) || $invocant;
  my $self = {};

  $self->{is_init}                     = undef;
  $self->{Filter}                      = undef;

  bless ($self, $class);
  return $self;

Или функции тоже нужно как то хитро заносить в self? 
Пробовал указатели сохранять в  self ничего хорошего из этого не получилось.

Автор: ginnie 30.3.2009, 17:59
myth777, покажите что хранится в массиве

Код

use Data::Dumper;
print Dumper($self->{Mas_mDsGUI});

Автор: myth777 30.3.2009, 18:12
Все выводить не стану много конфедец.
Код

bless( 
{ 'ModifedRecordStruc' => {}, 'Fields' => { 'house' => '(Integer)', 'street' => '(String)',  
'Table' => 'clients_addresses', 
 'is_init' => 1, 'ActiveTemplate' => undef }, 'mDSGUI' ), 



И таки х Bless-ов несоклько в массиве. Говорю же массив содержит указатели на классы.
Функциями в дампе и не пахнет. Мож их тоже как нибуть Bless-ить? smile))

Автор: ginnie 30.3.2009, 19:52
myth777, интересно Вы программу пишите с использованием объектов и так много про них не знаете.

То, что Вы привели - объект класса mDSGUI. Что такое "указатели на классы" мне не известно.
Для решения возникшей проблемы я бы добавил 

Код

warn $i;
warn ref $self->{Mas_mDsGUI}->[$i];
print  $self->{Mas_mDsGUI}->[$i]->PrintOk();

Автор: myth777 30.3.2009, 21:45
Perl очень спецефический язык, на котором пишу всего  два месяца. Поэтому и не знаю многих вещей.
Ваш пример не работает.

Код

Can't call method "PrintOk" on unblessed reference at C:/Server/wwwroot/cgi-bin/lib//group_DSGUI.pm line 155.


Не видет он функцию и все тут. 

Автор: ginnie 30.3.2009, 21:51
myth777, код, который я привел и не должен был ничего починить. Он для отладки. Покажите последние строки до 

Код

Can't call method "PrintOk" on unblessed reference at C:/Server/wwwroot/cgi-bin/lib//group_DSGUI.pm line 155.


код должен вывести номер элемента массива и ссылкой на что этот элемент является.

Добавлено через 4 минуты и 25 секунд
Сообщение Can't call method "PrintOk" on unblessed reference означает, что элементом массива является ссылка, но структура данных (скорее всего хэш) по этой ссылке не является объектом. Нужно понять, как в массив попадает хэш, вместо объекта.

Добавлено через 6 минут и 27 секунд
Результат работы Dumper() показал, что часть элементов массива - нормальные объекты, следовательно надо узнать номер элемента массива, не являющегося объектом и узнать, как он туда попал.

Автор: myth777 30.3.2009, 22:21
Он только это и напечатал:

Код

Software error:
Can't call method "PrintOk" on unblessed reference at C:/Server/wwwroot/cgi-bin/lib//group_DSGUI.pm line 153.

 smile 

Код


может
sub GetInterphasemDSGUI
{
  my $mgui = mDSGUI->new();
  $mgui->init(\%has);
  return $mgui;
}

не работает? Типо как нибудь локально создает указатель на объект, а потом хрень какая нибудь в памяти получается?

Автор: NuINu 30.3.2009, 22:21
мне кажеться здесь простая проблема с приоритетом операций

можно попробовать так
Код

print  ${$self->{Mas_mDsGUI}->[$i]}->PrintOk();

Автор: myth777 30.3.2009, 22:23
Шустрый - 
на
Код

   ${$self->{Mas_mDsGUI}->[$i]}->PrintOk();


выдает
Software error:
Not a SCALAR reference at C:/Server/wwwroot/cgi-bin/lib//group_DSGUI.pm line 154.

Добавлено через 11 минут и 51 секунду
Заработало. Нашел багу.
Я дурак. В конструкторе класса проинициализировал массив на указатели моего класса

Код

   @{$self->{Mas_mDsGUI}} = undef;  

Из за этого первым элементом массива была чушь. (пустой хэш)

Всем спасибо, за советы. Молодцы - отписываете! 
Форум в избранное добавил уже.

Автор: GoDleSS 31.3.2009, 10:31
myth777, не забываем пользоваться Data::Dumper - ом, дабы проще было анализировать подобные ситуации, ага ;)

Автор: myth777 31.3.2009, 18:09
Ага smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)